16

我有一个带有 bean 管理事务的无状态 bean,以及这样的方法:

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class ... {

    @Resource 
    private UserTransaction ut;
    @EJB 
    private OtherStatelessBeanLocal other;

    public void invokeSomeMethods() 
        ut.begin();
        ...

        // invoke other bean's methods here.
        other.method();

        ...
        ut.commit();

    }

}

那么如何UserTransaction传播到OtherStatelessBeanLocalbean?

4

3 回答 3

32

UserTransaction对象是由容器提供的对象,它封装了对容器内部使用的 API 调用的访问,特别是javax.transaction.TransactionManager。有TransactionManager方法,如begin, commit,rollbackjavax.transaction.Transaction getTransaction()

在幕后,TransactionManager 将使用ThreadLocal或类似技术来跟踪线程的当前事务状态。ThreadLocals 是非常简单的对象,可以很容易地描述为static HashMap使用线程名称作为键和您选择的对象作为值的对象。只要您留在同一个线程中,您就可以从调用链中的任何点获取对象。这是不允许在 Java EE 环境中启动线程的原因之一。

安全传播以类似的方式工作,就像神奇地指向正确模块或组件的java:comp/env名称空间的 JNDI 查找一样。底线是您无法实现没有 ThreadLocals 的应用服务器。传播听起来比实际上更活跃,而实际上它只是不离开线程的行为,因此容器和所有相关人员仍然可以找到您的“东西”。

回到事务管理术语,TransactionManager 将在其 ThreadLocal 中跟踪的对象通常会(直接或间接)实现TransactionTransactionSynchronizationRegistry接口。在这两个接口之间,容器拥有它所需要的所有钩子来代表你跟踪当前事务中的DataSources、EntityManagers 和其他资源。这些接口还允许容器提供诸如SessionSynchronization之类的回调,以及在事务完成时代表您执行其他操作的方法,例如刷新/关闭 EntityManager、发送 JMS 挂起消息以及持久化您的应用程序在课程中创建的任何计时器的交易。

于 2010-11-09T21:57:35.977 回答
4

根据 EJB 规范,您不能使用编程事务将事务上下文从 bean(在本例中为您的主类 ...)传递到使用编程事务的另一个 bean(在本例中为其他)

于 2011-01-08T04:57:54.257 回答
0

对于 EJB3,您通常使用 @TransactionAttribute 注释定义事务传播。

所有 EJB 3.0 应用程序的默认事务属性都是必需的:

如果客户端在客户端与事务上下文相关联时调用企业 bean 的方法,则容器在客户端的事务上下文中调用企业 bean 的方法。

交易类型的文档在这里:http: //download.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html

NB 持久性上下文和事务传播通常同时发生,但并不总是 - 请注意。例如,有状态会话 bean 可能具有扩展的持久性上下文

于 2010-11-09T22:10:41.753 回答