【问题标题】:Does application exception roll the transaction back?应用程序异常是否回滚事务?
【发布时间】:2015-12-05 23:50:55
【问题描述】:

我有一个无状态的 bean 类 TestBean:

package samples;

import javax.ejb.*;
import javax.persistence.*;

@Stateless
public class TestBean {
    @PersistenceContext
    EntityManager em;

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void doIt() throws Exception {
        em.createQuery("UPDATE Employee e SET e.salary = e.salary * 1.05").executeUpdate();
        throw new Exception("Let us stop it!");
    }
}

EntityManager 是否提交事务并进行更新?

【问题讨论】:

  • 当你尝试它时会发生什么?我们无法真正明确地告诉您是或否,因为我们不知道您的完整环境是什么。理论上,是的,事务应该回滚。您为什么不尝试一下并告诉我们。
  • @DuncanKinnear 这是一个纯粹的 JPA 问题,而不是像 Hibernate 这样的实现。

标签: jpa ejb entitymanager


【解决方案1】:

默认情况下,EJB bean 应该只在系统异常时回滚事务,即:RuntimeException、RemoteException。这种异常被封装在 EJBException 中。

如果您抛出应用程序异常(就像在您的示例中一样),EJB bean 不会回滚事务 - 它希望您处理异常。应用程序异常是那些不扩展 RuntimeException 或 RemoteException 的异常。

您可以通过以下注释使您的 EJB bean 回滚应用程序异常:

@ApplicationException(rollback=true)

【讨论】:

  • 这意味着具有 REQUIRES_NEW 的方法不应抛出捕获的(应用程序)异常。
  • REQUIRES_NEW 与 EJB 中的异常处理无关。它指定 EJB bean 使用新事务运行业务方法(例如,当您从另一个业务方法调用一个业务方法时 - 默认情况下,它们共享相同的事务)。
  • REQUIRES_NEW 总是启动一个新事务(在调用者开始一个新事务之前暂停它的事务,并在它完成后恢复它)。如果您想在您的方法中发生应用程序异常时将事务标记为回滚,请从您的 catch 块中调用 setRollbackOnly() 方法。然后容器在方法完成后立即回滚事务
猜你喜欢
  • 2013-10-16
  • 1970-01-01
  • 2012-12-28
  • 2019-04-30
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2015-10-03
相关资源
最近更新 更多