16

Java EE 6 CDI 事件是事务性的吗?

如果我在事务中触发事件,然后回滚事务,事件侦听器的效果是否也会回滚?

这种行为是否依赖于事件侦听器本身支持事务?

如果我尝试从事件侦听器中回滚异常,它会回滚触发事件的事务吗?

4

1 回答 1

17

从 CDI 1.0 规范的事件章节中,可以通过指定正在观察的 TransactionPhase 将事件定义为“事务性”,其中 TransactionPhase 是以下之一:

  • 进行中,
  • BEFORE_COMPLETION,
  • AFTER_COMPLETION,
  • AFTER_FAILURE,
  • AFTER_SUCCESS

这样的声明看起来像:

void onDocumentUpdate(@Observes(during=AFTER_SUCCESS) @Updated Document doc) { ... }

如果观察者未声明为“事务性”,则容器立即调用观察者,否则它使用 JTA 同步注册观察者方法以便在事务完成阶段稍后调用。

然而:

在事务完成之前调用的任何观察者方法都可以调用 setRollbackOnly() 来强制事务回滚。观察者方法不能直接启动、提交或回滚 JTA 事务。

如果观察者方法抛出异常(并且它本身不是“事务性的”),则异常中止事件处理。

因此,为了实现我正在寻找的行为,我相信我会将我的观察者注册为“事务性”,并指定 BEFORE_COMPLETION TransactionPhase。如果我想回滚启动事件的事务,我会调用 setRollbackOnly()。

于 2010-11-21T23:32:42.303 回答