Jakarta ee JEE事务:在何处指定回滚/回滚

Jakarta ee JEE事务:在何处指定回滚/回滚,jakarta-ee,jboss,transactions,cdi,java-ee-7,Jakarta Ee,Jboss,Transactions,Cdi,Java Ee 7,关于JEE事务注释的rollbackOn和dontRollbackOn的用法,我有一个问题。我做了一些研究,但只找到了关于 @Transactional(dontRollbackOn={SomeRuntimeException.class} 我可以/必须在哪里指定注释?两个选项对我来说很有意义,那么是哪一个 在类中发生RuntimeException “粘性”方法——当事务被创建时(在我的例子中是Requires_new),并且一旦事务被注释,它将相应地做出反应,而不管异常发生在何时何地 我非常

关于JEE事务注释的rollbackOn和dontRollbackOn的用法,我有一个问题。我做了一些研究,但只找到了关于

@Transactional(dontRollbackOn={SomeRuntimeException.class}

我可以/必须在哪里指定注释?两个选项对我来说很有意义,那么是哪一个

  • 在类中发生RuntimeException
  • “粘性”方法——当事务被创建时(在我的例子中是Requires_new),并且一旦事务被注释,它将相应地做出反应,而不管异常发生在何时何地
  • 我非常想要第二个版本,因为我创建了一个新的事务,它通过be业务层“传递”到与数据库相关的类。两个不同的业务函数使用特定的数据库方法,只有一个需要“dontRollbackOn”函数

    但是目前在我的情况下(JBoss7EAP,JEE7,Java1.8),只有版本1可以工作

    @Transactional(dontRollbackOn = {SomeRuntimeException.class}
    public void doSomething(){
     ...
     Query query = this.getEntityManager().createQuery(...);
     query.setParameter(...);
     queryResult = query.getSingleResult();
    }
    

    有人可以分享一些信息吗?

    假设您使用的是默认情况下随事务处理一起提供的EJB无状态bean,您可以使用
    Context.setRollbackOnly()
    控制事务回滚(注入EJB上下文,并在catch块中,根据需要将其设置为回滚),或使用您希望回滚的服务方法引发的自定义异常类型。此异常需要具有
    @ApplicationException(rollback=true)
    注释存在。第二个选项是处理EJB中事务机制的非常方便和干净的方法,从业务方法的声明中可以清楚地看出,无论它是否在错误时回滚,例如
    public void handleRegistration()抛出MyServiceException
    。每当容器遇到服务调用,这将导致您的MyServiceException,它将回滚当前事务(如果存在)

    如果抛出
    RuntimeException


    更多信息可以在免费电子书中找到

    假设您使用的是默认事务处理附带的EJB无状态bean,您可以使用
    Context.setRollbackOnly()
    控制事务回滚(注入EJB上下文,并在catch块中,根据需要将其设置为回滚),或使用您希望回滚的服务方法引发的自定义异常类型。此异常需要具有
    @ApplicationException(rollback=true)
    注释存在。第二个选项是处理EJB中事务机制的非常方便和干净的方法,从业务方法的声明中可以清楚地看出,无论它是否在错误时回滚,例如
    public void handleRegistration()抛出MyServiceException
    。每当容器遇到服务调用,这将导致您的MyServiceException,它将回滚当前事务(如果存在)

    如果抛出
    RuntimeException


    更多信息可以在免费电子书中找到。不幸的是,您需要在引发异常的EJB方法上执行此操作。否则,异常传播将在方法调用边界处标记事务以进行回滚。因此,这是您文章中的答案(1)

    一些进一步的建议:

    处理意外异常的最佳方法是让它们冒泡出来,并在UI边界附近的某个地方处理它们。因为它们是意外的,所以通常不希望提交任何事务,因为这会使应用程序处于不一致的状态

    但是,您的示例代码提供了一种实际可能会出现异常的情况。在这种情况下,您应该在原始方法中处理它们:

    try {
        Query query = this.getEntityManager().createQuery(...);
        query.setParameter(...);
        queryResult = query.getSingleResult();    
        ...
    } catch (NoResultException e) {
        // What are the business rules when NoResultException happens?
    } catch (NonUniqueResultException e) {
        // What are the business rules when NonUniqueResultException happens?
    }
    

    如果其中一个或两个都是意外的,那么第1段仍然适用。

    不幸的是,您需要在引发异常的EJB方法上执行此操作。否则,异常传播将在方法调用边界处标记要回滚的事务。因此,这是您文章中的答案(1)

    一些进一步的建议:

    处理意外异常的最佳方法是让它们冒泡出来,并在UI边界附近的某个地方处理它们。因为它们是意外的,所以通常不希望提交任何事务,因为这会使应用程序处于不一致的状态

    但是,您的示例代码提供了一种实际可能会出现异常的情况。在这种情况下,您应该在原始方法中处理它们:

    try {
        Query query = this.getEntityManager().createQuery(...);
        query.setParameter(...);
        queryResult = query.getSingleResult();    
        ...
    } catch (NoResultException e) {
        // What are the business rules when NoResultException happens?
    } catch (NonUniqueResultException e) {
        // What are the business rules when NonUniqueResultException happens?
    }
    

    如果其中一个或两个都是出乎意料的,那么第一段仍然适用。

    不,我们使用的是JBoss7EAP版本,即JavaEE7()澄清在帖子中…您是否正在尝试处理和?有更简单的管理方法,您更简单的方法是什么?如javadoc中所述,当前事务不会为这两个事务回滚:“此异常不会导致当前事务(如果一个事务处于活动状态)标记为回滚。”(但根据我的经验,这在不同的jee服务器中处理方式不同…)但我的问题是如何处理任何其他运行时异常…不,我们使用的是JBoss7EAP版本,即JavaEE7()澄清在帖子中…您是否正在尝试处理和?有更简单的管理方法,您更简单的方法是什么?如javadoc中所述,当前事务不会为这两个事务回滚:“此异常不会导致当前事务(如果一个事务处于活动状态)标记为回滚。”(但根据我的经验,这在不同的jee服务器中处理不同…)但我的问题是如何处理任何其他运行时异常…我认为OP更感兴趣的是不回滚当前事务。对,我应该澄清一下,有两种方法-容器管理事务(EJB)