2010-11-07 17 views
16

我有bean管理的事务无状态Bean和方法是这样的:UserTransaction如何传播?

@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传播到OtherStatelessBeanLocal豆?

+0

好它没有,对吧? – 2014-11-11 22:32:17

回答

32

UserTransaction对象是由容器提供的对象,它包装对容器在内部使用的API调用的访问,特别是javax.transaction.TransactionManager。该TransactionManager有像begincommitrollbackjavax.transaction.Transaction getTransaction()

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

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

回到事务管理术语来说,TransactionManager将在其ThreadLocal中跟踪的对象通常会(直接或间接)实现接口TransactionTransactionSynchronizationRegistry。在这两个界面之间,该容器拥有所有必要的挂钩以代表您在当前交易中跟踪DataSource s,EntityManager和其他资源。这些接口还允许容器提供回调,例如SessionSynchronization,以及在交易完成后代表您执行其他事情的方式,例如刷新/关闭EntityManagers,发送JMS待处理消息以及在应用程序中持久保存由您的应用创建的任何计时器的交易。

+2

完美答案。+1 – 2010-11-10 02:40:02

+0

其实不是,因为它不会将知识应用于问题。 – Thomas 2017-11-03 07:26:19

0

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

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

如果一个客户端调用企业Bean的方法,同时在客户端与事务上下文关联,容器调用企业Bean的方法在客户端的事务上下文。

的交易类型的文档的当前位置:http://download.oracle.com/javaee/6/api/javax/ejb/TransactionAttributeType.html

注:持久性上下文和事务传播通常会一起发生,但并非总是如此 - 要小心。例如,有状态会话bean可能有一个extended persistence context

+0

注意,在EXTENDED持久化上下文的情况下,持久化上下文仍然只与事务相关联,并且不可用于其他事务,因为只要持有@Stateful bean参与事务,就不允许离开事务直到它提交或回滚。从事务外的所有对@Stateful bean的请求都会等待@AccessTimeout的持续时间,然后才抛出某种形式的ConcurrentAccessException。 – 2010-11-10 03:53:09

4

基于EJB规范中,则可以使用编程式的事务到另一个bean(在这种情况下,其他)使用程序交易没有通过从一个bean事务上下文(在这种情况下,你的主类...)