异步方法的默认EJB事务模式是什么?

36
  1. 如果我在EJB中有一个@Asynchronous方法,并且我没有指定@TransactionAttribute,那么容器如何处理事务边界?显然,它不能使用调用线程的事务,那么它会怎么做呢?

  2. 同样的问题,但涉及到由TimerService触发的方法。


编辑:我想我的措辞不太好。 我已经知道默认模式是'REQUIRED',所以可以安全地假设这些方法将始终在事务中被调用。 但我的问题是,该事务的生命周期是什么样的? 容器是否为每次调用创建一个新的事务? 或者它会在异步工作线程上的所有调用中重复使用相同的事务? 如果是后者,那么事务何时关闭?

2个回答

46
类似于 MDB,容器会在您的 @Asynchronous@Schedule@Timeout 方法(和适用的拦截器)被实际调用之前启动事务,并在方法(和拦截器)完成后提交事务。通常情况下,该事务会传播到方法中调用的所有 bean 以及那些 bean 递归调用的所有 bean。当然,其他被调用的 bean 可以通过指定其他的 @TransactionAttribute 设置(例如 REQUIRES_NEWNOT_SUPPORTED)来更改它们方法调用的事务语义。
顺便提一句,事务不会传播到带有 @TransactionManagement(BEAN) 的 bean。在调用 Bean-Managed Transaction bean 上的方法之前,容器将始终挂起任何正在进行的事务。
编辑:
更直接地回答编辑后的问题:在 Java 事务 API 中没有方法可以让一个事务跨越多个线程,因此在 EJB 中也没有这种方法。每个 @Asynchronous 调用都与调用者的事务(如果有)完全断开连接。您基本上会得到一个新的事务、没有事务或异常,具体取决于您使用的 @TransactionAttribute。从 TimerService 中调用同样如此。

3
请注意,这个回答似乎与下面的回答相反(可能取决于EJB版本)。 - BillMan
1
@BillMan请让我知道哪些地方似乎存在冲突,我会更新答案以澄清。 - David Blevins
1
@DavidBlevins 对不起,我误解了你原来的回答。现在重新阅读后似乎没有任何冲突。如果您愿意的话,我可以删除原始内容。但是如果您保留它,这对我的谦卑可能会有好处 :). - BillMan
2
@BillMan 嘿嘿,别担心。这是有趣的交流。如果你不得不读两遍,那可能还是我的错。 :) - David Blevins
4
很好的回答,我不得不读两遍。对于其他阅读此评论的人(如上下所述),异步方法将启动一个新的事务。 - dngfng
只是让大家知道,这里的回答者David Blevins是一位Java Champion,他在EJB规范的制定方面工作(还有CDI等其他方面,https://www.linkedin.com/in/dblevins)。因此,你从他那里读到的每一个答案都可以被认为是真实可靠的来源 :) 谢谢David。 - gmanjon

37

来源于EJB 3.1规范。

4.5.3 事务

在异步方法调用中,客户端事务上下文无法传播。从Bean开发者的角度来看,永远没有来自客户端的事务上下文。这意味着,例如,在异步方法上的REQUIRED事务属性的语义与REQUIRES_NEW完全相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接