2

我有一个@Stateless EJB 方法,其中我

  1. remove()使用 JPA 从数据库中删除一些条目
  2. 抛出一个注释为的异常@ApplicationException(rollback=true)

我对该方法没有其他特定于事务的注释(我设置@TransactionAttribute(TransactionAttributeType.REQUIRED)了,但无论如何这应该是默认值!)。事务是容器管理的。JPA 提供者是 EclipseLink。

而且,当抛出异常时,事务不会回滚。例如。我在回滚之前从数据库中删除的条目不会回来。顺便提一句。我在抛出之前调用 entityManager.flush(),它会导致这种行为(它不应该)吗?

我也尝试调用SessionContext.setRollbackOnly(),结果相同。

我该如何调试这个问题?

我正在使用 Glassfish v3 和 Netbeans 进行调试,但我对 println 也同样满意,我只是不知道把它们放在哪里......

4

2 回答 2

2

我有一个@Stateless EJB 方法,其中我(...)

只是为了澄清你如何获得EntityManager?

(...)我设置 @TransactionAttribute(TransactionAttributeType.REQUIRED

事实上,这是默认设置,无论如何都不应该被要求。

而且,当抛出异常时,事务不会回滚。例如。我在回滚之前从数据库中删除的条目不会回来。

嗯,这很奇怪,也很意外。

顺便提一句。我在抛出之前调用 entityManager.flush(),它会导致这种行为(它不应该)吗?

不,刷新!=提交

我还尝试调用 SessionContext.setRollbackOnly(),结果相同。

好吧,仍然出乎意料(但至少是一致的......)。

我正在使用 Glassfish v3 和 Netbeans 进行调试

也许激活以下类别的日志记录(例如,通过配置 > 日志记录 > 日志级别下的管理控制台),看看你是否能发现任何奇怪的东西:

  • javax.enterprise.system.core.transaction
  • javax.enterprise.resource.jta
  • javax.enterprise.system.container.ejb

作为替代方案(类似于“穷人的日志记录”),您可以实施SessionSynchronization以获取有关事务的通知。

真是奇怪的问题……

也可以看看

于 2010-10-26T16:11:30.830 回答
2

除了 Pascal 的好答案之外,还有一些事情要检查......如果以下任何一项为真,EntityManager则保证您不会参与容器管理的事务:

  • 您通过 EntityManagerFactory 创建了 EntityManager
  • transaction-type="RESOURCE_LOCAL"在 persistence.xml 中指定

次要检查事项:

  • <jta-data-source>在persistence.xml中填写
  • 通过引用的 DataSource<jta-data-source>设置为参与 JTA 事务(自动提交关闭)

最后两个在某种程度上是特定于供应商的,因为<jta-data-source>如果未指定,一些供应商会自动填写。同样,如果<jta-data-source>指向未设置为参与 JTA 事务的 DataSource(该设置是特定于供应商的),则有些部署将失败。不确定 Glassfish 如何处理这两个项目。

于 2010-10-28T04:47:04.987 回答