@Stateless
public class MyBean1 {
pulic void method1() {
//method implementation
}
pulic void method2() {
//method implementation
}
}
考虑MyBean1
的特定实例。然后我们知道多个线程不能同时访问method1()
或method2()
。但是,虽然线程正在访问method1()
,但是另一个线程可以访问method2()
吗?
答案 0 :(得分:3)
我认为ejb 3.1规范的第4.3.14节给出了答案。
4.3.14序列化会话Bean方法
以下要求适用于无状态和有状态会话Bean。 有关Singleton会话bean并发要求,请参见第4.8.5节。容器序列化对每个有状态和无状态会话bean实例的调用。 大多数容器将支持并发执行的会话bean的许多实例; 但是,每个实例只能看到序列化的方法调用序列。 因此,有状态或无状态会话bean不必编码为可重入。
容器必须序列化所有容器调用的回调 (即业务方法拦截器方法,生命周期回调拦截器方法, 超时回调方法,beforeCompletion等),它必须序列化这些回调 使用客户端调用的业务方法调用。
...
据我了解EJB规范,如果你想要对并发进行细粒度控制(bean托管,容器管理),你应该使用Singletons。
答案 1 :(得分:1)
让我们稍微修改你的例子
@Stateless
public class MyBean1 {
@Resource
private SessionContext sessionContext;
pulic void method1() {
// method implementation
// As a side-effect, something is written into a database
// using an XA data source,
// and a message is sent using XA JMS
// (both under control of an XA transaction)
}
pulic int method2(int i) {
return i * i;
}
}
例如,会话上下文用于获取UserTransaction
和getCallerPrincipal
。它们不一定总是相同的(当两个客户端都是EJB时)。至于UserTransaction
:这个绑定到当前线程(参见Javadoc)。
由于会话上下文存储在字段中(并且未向每个单独的方法传递参数),因此两个不同的客户端无法访问相同的EJB实例。
因此规范要求容器序列化调用到同一个实例。
如果你看一下method2
,一个没有任何副作用的纯功能实现,就不需要EJB。