[转载]EJB 倡导者: 有状态会话 Bean 的实际使用

2024-02-21 18:20

本文主要是介绍[转载]EJB 倡导者: 有状态会话 Bean 的实际使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

EJB 倡导者: 有状态会话 Bean 的实际使用


正当您认为某个给定的组件没有什么用处的时候,比如有状态会话 EJB,可能正好会出现适合应用该组件的场景。在本系列的上一期专栏中,EJB 倡导者研究了一些棘手的情况,它们有时需要提供长时间运行的服务。

摘自 IBM WebSphere 开发者技术期刊。

在每次专栏中,EJB 倡导者都罗列出与实际客户和开发人员来来回回对话交流的要点,并在期间针对某一大家关注的设计问题推荐解决方案。我们去除了一些特定的细节,也避免提出“革新的”或专有的体系结构.有关详细信息,请参见 EJB 倡导者简介。

对于有状态会话 Bean,是否存在非常有价值的情况呢?

亲爱的 EJB 倡导者:

似乎除了有状态会话 Bean 之外,您已经为所有的 EJB 组件类型找到了合适的用途。有状态会话 Bean 是“最差”的实践或其他的什么情况吗?

署名:
Is Something Rotten in the State?


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


其主要用途是在多个事务之间管理状态信息

亲爱的 Something Rotten:

从您的来信中我可以推断出,您曾阅读过我以前的专栏,并且知道我的格言“没有不好的模式,只有不好的模式应用”。这句话说明,对于有些组件,比如有 状态会话,仅适用于很少的场合,但是在这些情况下,它们可能是最简单并且最有效的解决方案,并且在这些情况下,使用其他更常见的组件,比如无状态会话,可 能会更加复杂,并且是更糟糕的解决方案。

例如,假设您有一个应用程序,它必须遍历数据库中大量行。说得具体一点,假设您需要重新计算手头每件库存产品的价格,并计算其总和。您可能希望一次 处理给定数目的行(或者在某个特定的时间段内),这样一来,就不会出现事务超时或因为在单个事务中占用过多的资源而出现内存溢出的情况。

使用有状态会话 Bean,客户端的逻辑业务可能非常简单,如下所示:

RevaluationServiceHome home =
(RevaluationServiceHome)initCtx.lookup(
"java:comp/env/RevaluationService"
);
ReValuationService service = home.create();
while (service.revalueNextBlock(50)) {}
double totalValue = service.getTotalValue();
service.remove();

执行了这段代码之后,对所有的行进行了更新,并设置了 totalValue。因为每个方法在其自己的事务中执行,所以您不需要关心如何管理客户端事务。仅有一件棘手的事情需要记住,在完成之后,需要调用会话 的 remove() 方法,特别是对于远程的会话、或者是在循环中调用这段代码的时候。其原因是,每次在调用 create 方法的同时,创建了一个新的实例。

有状态会话 EJB 组件的实现同样可以非常简单:

public class RevaluationService implements SessionBean {

double totalValue = 0.0;
transient Iterator inventory = null;

public void ejbCreate() {
InventoryHome home =
(InventoryHome)initCtx.lookup(
"java:comp/env/Inventory"
);
inventory = home.findAll().iterator();
totalValue = 0.0;
}

public boolean revalueNextBlock(int count) {
for (; count > 0; count--) {
if (inventory.hasNext()) {
Inventory item = (Inventory)inventory.next();
totalValue += item.revalue();
}
else {
return false;
}
return true;
}

public double getTotalValue() { return totalValue; }

public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbRemove() {}
}

假设有一个名为 Product 的实体 EJB 组件,其中具有一个用来计算并返回价格的方法。但它是分离关注点的关键,我们在这些专栏中讨论过这个问题。

希望这对您有所帮助。

好的,就先到此为止,
您的 EJB 倡导者


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


利用激活和钝化瞬态变量来启用池机制

亲爱的 EJB 倡导者:

这确实有所帮助。我思考了很久,如何能够在不使用有状态会话 EJB 组件的情况下完成相同的任务。

但是当我看到您为名为“inventory”的 Iterator 使用 transient 关键字的时候,我便意识到这段代码无法工作,因为您没有实现 ejbActivate() 和 ejbPassivate() 方法。我的理解是,当会话 EJB 池中分配的实例数目达到最大值,并且创建了一个新实例的时候,某个不幸的活动实例将会被钝化。然后,当某个不活动的实例的下一个事务到来时,再将其激活

如果在您的实现中不对实例进行钝化,那么“inventory”Iterator 将为空,或者更糟,具有来自另一个对话的未定义的值。

我认为您应该在 ejbPassivate() 中将当前位置保存到一个变量中,并重新启动 ejbActivate() 中的查询,如下所示:

public class RevaluationService implements SessionBean {

double totalValue = 0.0;
InventoryKey lastKey = null;
transient Iterator inventory = null;
transient Inventory item = null;

public void ejbCreate() {
InventoryHome home =
(InventoryHome)initCtx.lookup(
"java:comp/env/Inventory"
);
inventory = home.findAll().iterator();
totalValue = 0.0;
last = null;

}

public boolean revalueNextBlock(int count) {
for (; count > 0; count--) {
if (inventory.hasNext()) {
item = (Inventory)inventory.next();
totalValue += item.revalue();
}
else {
return false;
}
return true;
}

public double getTotalValue() { return totalValue; }

public void ejbActivate() {
InventoryHome home =
(InventoryHome)initCtx.lookup(
"java:comp/env/Inventory"
);
inventory = home.findAfter(lastKey).iterator();
}
public void ejbPassivate() {
if (item == null) {
lastKey = null;
}
else {
lastKey = item.getPrimaryKey();
}
}
public void ejbRemove() {}
}

署名:
Not Feeling So Rotten About State Anymore


blue_rule.gif
c.gif
c.gif
u_bold.gif回页首


始终让实现适应设计

亲爱的 Not So Rotten:

我不得不承认我的实现在具有多客户端的远程环境中,并不像您的代码那样合适。然而,您是否考虑到了我的场景中的具体情况,即在单个“会话”中处理整 个数据库(从创建到删除)。在设计过程中必须考虑到,可能每台服务器仅有一个客户端(为了实现最好的性能,会话 Bean 可能与数据库共存)。

我还要承认的是,对于这些设计中的假设,如果能够在 ejbActivate() 和 ejbPassivate() 方法中引发某种系统异常,以便在失败时提供更好的错误消息,而不是您在碰到空指针时所获得的消息,那么这样做可以使得系统更加健壮。

但是为什么我正感觉到是您在引导着我呢?也许您就是将来撰写本专栏的人选!

顺便说明一下,明年我将要从事新的工作,可能很少有时间撰写关于 EJB 的专栏了,所以在短期之内,这将是我这个专栏的最后一期。感谢两年以来曾阅读和评论过这些专栏的所有读者。我非常高兴能够作为:

您的 EJB 倡导者

好的,就先到此为止,

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/374079/viewspace-130647/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/374079/viewspace-130647/

这篇关于[转载]EJB 倡导者: 有状态会话 Bean 的实际使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/732659

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

hdu1565(状态压缩)

本人第一道ac的状态压缩dp,这题的数据非常水,很容易过 题意:在n*n的矩阵中选数字使得不存在任意两个数字相邻,求最大值 解题思路: 一、因为在1<<20中有很多状态是无效的,所以第一步是选择有效状态,存到cnt[]数组中 二、dp[i][j]表示到第i行的状态cnt[j]所能得到的最大值,状态转移方程dp[i][j] = max(dp[i][j],dp[i-1][k]) ,其中k满足c

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的