2
@Stateless
public class MyBean1 {

    pulic void method1() {
        //method implementation
    }

    pulic void method2() {
        //method implementation
    } 
}

考虑一个特定的实例MyBean1。然后我们知道method1()或者method2()不能被多个线程同时访问。但是,当method1()被一个线程访问时,可以method2()被另一个线程访问吗?

4

2 回答 2

3

我认为 ejb 3.1 规范的第 4.3.14 节给出了答案。

4.3.14 序列化会话 Bean 方法
以下要求适用于无状态和有状态会话 bean。有关 Singleton 会话 bean 并发性要求,请参阅第 4.8.5 节。

容器序列化对每个有状态和无状态会话 bean 实例的调用。大多数容器将支持同时执行的会话 bean 的多个实例;但是,每个实例只能看到一个序列化的方法调用序列。因此,有状态或无状态会话 bean 不必编码为可重入的。

容器必须序列化所有容器调用的回调(即业务方法拦截器方法、生命周期回调拦截器方法、超时回调方法、beforeCompletion等),并且必须将这些回调与客户端调用的业务方法调用序列化.

……

据我了解 EJB 规范,如果您想要对并发进行细粒度控制(bean 管理,容器管理),您应该使用 Singletons。

于 2013-08-02T04:32:58.000 回答
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;
    } 
}

例如,会话上下文用于获取UserTransactionand getCallerPrincipal。它们不一定总是相同的(当两个客户端都是 EJB 时)。至于UserTransaction:这个绑定到当前线程(参见Javadoc)。

由于会话上下文存储在一个字段中(并且没有将参数传递给每个单独的方法),因此两个不同的客户端不能访问同一个 EJB 实例。

因此规范要求容器序列化对同一实例的调用。

如果您看一下method2,一个没有任何副作用的纯函数式实现,就不需要 EJB。

于 2013-08-02T06:34:25.287 回答