回滚后的EJB 3.0 CMP事务

时间:2011-12-09 14:07:49

标签: ejb-3.0

我在EJB3.0中遇到了一些事务管理问题。我想要做的是在发生异常时将错误记录到数据库中。

为此,我有2个无状态bean:Bean ABean B

Bean A执行以下操作:

  1. 保存一些东西
  2. 如果需要,请致电Bean B以记录错误
  3. 在第1步中,保存基本上使用EntityManager#merge(-)方法。 在第2步中,我将以下行放在Bean B

    的顶部
    @Stateless(name = "ErrorLogDAO", mappedName = "ErrorLogDAO")
    @Remote
    @Local
    @TransactionManagement(TransactionManagementType.CONTAINER)
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public class ErrorLogDAOBean {...}
    

    但是,当在save方法中发生异常时,我正在捕获它,然后我手动调用ctx.setRollBackOnly()方法,之后我调用ErrorLogDAOBean将错误日志插入到D B。但是没有插入错误日志,我得到的错误是:

      

    javax.transaction.TransactionRolledbackException:EJB异常::   weblogic.transaction.internal.AppSetRollbackOnlyException at   weblogic.transaction.internal.TransactionImpl.setRollbackOnly(TransactionImpl.java:551)     在   weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly(TransactionManagerImpl.java:319)     在   weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly(TransactionManagerImpl.java:312)     在   org.eclipse.persistence.transaction.JTATransactionController.markTransactionForRollback_impl(JTATransactionController.java:145)     在   org.eclipse.persistence.transaction.AbstractTransactionController.markTransactionForRollback(AbstractTransactionController.java:196)     在   org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.rollbackTransaction(UnitOfWorkImpl.java:4486)     在   org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1351)     在   org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:468)     在   org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet(UnitOfWorkImpl.java:1439)     在   org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges(RepeatableWriteUnitOfWork.java:316)     在   org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush(EntityManagerImpl.java:527)   ....

    我对事务管理逻辑非常熟悉,基于上面的代码,我假设我已经覆盖了这个,但似乎没有。

    有什么想法吗?

    更新

    Bean A代码:

    @TransactionManagement(value = TransactionManagementType.CONTAINER)
    @TransactionAttribute(value = REQUIRED)
    public class WMServiceBOBean {
    
    public void saveInBeanA {
    
         int errorCode = save();
    
         if (errorCode != SUCCESS)
         { 
       ClassX.logError();
       ctx.setRollbackOnly();
       return errorCode;
         }
       }
    }
    

    X类代码:

    public class classX
    {
     ...
     public void logError()
     {
       ErrorLog e = new ErrorLog;
       BeanB beanB = //Local lookup of Bean B
       beanB.insertErrorLog (e);
     }
     ...
    }
    

    BEAN B代码:

    @TransactionManagement(TransactionManagementType.CONTAINER)
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public class ErrorLogDAOBean
    {
     ...
     public void insertErrorLog (ErrorLog e)
     {
       merge (e);
     }
     ...
    }
    

1 个答案:

答案 0 :(得分:1)

我终于找到了问题。

这是问题所在,当查找ErrorLogBean时,我正在实例化一个新的Persistence Manager。当事务被标记为回滚时,获取新PM的过程失败。我知道获得一个新的持久性管理器是没有意义的,但它是我们正在进行的测试的一部分。

感谢Piotr为您提供的所有帮助!