用户事务如何传播?

我有一个具有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();

    }

}

那么如何传播到豆子呢?UserTransactionOtherStatelessBeanLocal


答案 1

该对象是由容器提供的对象,它包装对容器内部使用的API调用的访问,特别是javax.transaction.TransactionManager。具有类似 、 和 的方法UserTransactionTransactionManagerbegincommitrollbackjavax.transaction.Transaction getTransaction()

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

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

回到事务管理术语中,事务管理器将在其 ThreadLocal 中跟踪的对象通常将(直接或间接)实现事务事务同步注册表接口。在这两个接口之间,容器具有代表您跟踪当前事务中的 s、s 和其他资源所需的所有挂钩。这些接口还允许容器提供回调(如 SessionSynchronization),以及在事务完成时代表你执行其他操作的方法,如刷新/关闭 EntityManagers、发送 JMS 挂起消息以及保留应用在事务过程中创建的任何计时器。DataSourceEntityManager


答案 2

基于 EJB 规范,您不能使用编程事务将事务上下文从使用编程事务的 Bean(在本例中是主类 ...)传递到另一个 Bean(在本例中为 other)。


推荐