weblogic.transaction.internal.AppSetRollbackOnlyException:在事务上调用setRollbackOnly

时间:2017-11-02 18:17:34

标签: java transactions ejb

我有下面的情况,我调用BeanA的doSomeTask(),但是如果doSomeTask()失败,我想将ErrorInfo持久化到另一个表中,同时调用BeanA的saveError(ErrorInfo)。它们都有@TransactionAttribute(REQUIRES_NEW)。

class BeanA {

    @TransactionAttribute(REQUIRES_NEW)
    public void doSomeTask(){

       if(someCondition){
          throw new SomeException();
       }

       // do task  
    } 

    @TransactionAttribute(REQUIRES_NEW)
    public void saveError(ErrorInfo error) {
          // save error info if doSomeTask fails
    }
}

 class BeanB {

     BeanA beanA;

     void performTask(){
           try{
              beanA.doSomeTask();     
            }catch(Exception e){
              ErrorInfo error = getErrorInfo(e)
              beanA.saveError(error);  
            }
     }   
 }

但是当doSomeTask()抛出异常时,saveError()不起作用并抛出异常

Caused by: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction

我做错了什么以及如何解决此错误?在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我不久前调试了类似的问题。就我而言,问题如下:

  • 在调用REQUIRES_NEW方法
  • 时打开了一个顶级事务
  • 在嵌套事务提交异常后,顶级别的提交无法提交为“仅标记为回滚”

事实证明,通过启动新事务,连接持有者将在TransactionManager级别共享。在嵌套事务中抛出异常时,连接本身仅标记为回滚。所以后来这就引起了这个问题。

我能够通过使用保存点(自JDBC 3.0以来可用)解决该问题。通常,默认情况下在许多环境/ ORM中禁用保存点,使用它们需要额外配置。

希望这有一些帮助。

答案 1 :(得分:0)

对不起,对于迟到的回答。问题解决了。

隐藏了实际错误。在我的例子中,实际错误只是在持久化时ErrorInfo实例的JSR 303验证错误。不得不添加

Dweblogic.transaction.allowOverrideSetRollbackReason=true

<{1>} <domain_home>/bin/setDomainEnv.sh找出实际错误并修复它。感谢这个答案https://stackoverflow.com/a/38584687/1563286