简体   繁体   English

事务回滚后调用非事务方法

[英]Calling non-transactional method after transaction is rolled back

I've just found some EJB behaviour which looks rather surprizing to me. 我刚刚发现了一些EJB行为,这对我来说似乎很令人惊讶。

Here is the code sample (for sure MyBean, beanA, beanB are EJBs using CMT): 这是代码示例(确保MyBean,beanA,beanB是使用CMT的EJB):

@Stateless
public class MyBean {
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void myMethod(){
         try {
             beanA.methodA(); /* annotated as REQUIRED */
         } catch (Exception e) {
             beanB.methodB(); /* annotated as NOT_SUPPORTED */
         }
    }
}

Lets's say methodA takes more than transaction timeout to execute, so once it returns myMethod receives TransactionRolledbackException, which is successfully caught then in "myMethod". 假设methodA花费了超过事务超时的时间,因此一旦返回myMethod,它就会收到TransactionRolledbackException,然后成功将其捕获到“ myMethod”中。

I would expect "methodB" be called so far, as accordingly with EJB spec it must be called without any transaction context. 我希望到目前为止,“ methodB”将被调用,因此,根据EJB spec,必须在没有任何事务上下文的情况下调用它。 But actually, the "beanB" proxy simply returns another TransactionRolledbackException, the "methodB" is not executed. 但实际上,“ beanB”代理仅返回另一个TransactionRolledbackException,“ methodB”未执行。

Looking through EJB spec I do not see anything to prove that container should or even might behave that way. 查看EJB规范,我没有发现任何证据可以证明容器应该甚至可能以这种方式运行。

Do I miss something? 我想念什么吗? Any hint would be appreciated. 任何提示将不胜感激。

UPDATE UPDATE

At least for Websphere, this behaviour appears to be timeout-specific. 至少对于Websphere,此行为似乎是特定于超时的。 The "rollbackOnly" flag which for example is set when "methodA" throws a RuntimeException, does not prevent "methodB" from execution. 例如,当“ methodA”引发RuntimeException时设置的“ rollbackOnly”标志不会阻止“ methodB”的执行。 Only timeout flag does. 只有超时标志可以。

The EJB specification does not specifically address this scenario, other than to indicate that once a transaction has been marked for rollback, then " Continuing transaction is fruitless ", and for the handling of NOT_SUPPORTED , the specification indicates it " does not prescribe how the container should manage the execution of a method with an unspecified transaction context ". EJB规范没有专门针对这种情况,只是指出一旦将事务标记为回滚,然后“ 继续事务是没有结果的 ”,并且对于NOT_SUPPORTED的处理,规范表明它“ 没有规定容器如何应该使用未指定的事务上下文来管理方法的执行 ”。

All versions of WebSphere Application Server have taken the approach that the best way to handle the scenario where an EJB method has been marked for rollback only is to prevent all further actions the container has control over, so that the transaction may be rolled back as quickly as possible, ensuring the timely release of resources (such as database locks). 所有版本的WebSphere Application Server都采用这样的方法来处理仅将EJB方法标记为回滚的方案的最佳方法是防止容器可以控制的所有其他操作,以便可以尽快回滚事务。尽可能确保及时释放资源(例如数据库锁)。 Allowing a call to a NOT_SUPPORTED EJB method would result in the marked for rollback transaction being suspended; 允许调用NOT_SUPPORTED EJB方法将导致标记为回滚的事务被挂起。 and thus continue to hold onto resources that could block or already be blocking other transactions. 因此会继续保留可能阻止或已经阻止其他事务的资源。 For this reason, WebSphere prevents such activity. 因此,WebSphere阻止了这种活动。

Faced the similar issue a while back . 不久前面临类似问题。 When the container mark the transaction for rollback you will not be able to do any other EJB calls after that. 当容器将事务标记为回滚时,此后您将无法执行任何其他EJB调用。 You can think about a solution of annotating @RequiresNew for beanA.methodA() , so that it will not share the global transaction of myMethod() and will always use new transaction. 您可以考虑为beanA.methodA()注释@RequiresNew的解决方案,以便它不会共享myMethod()的全局事务,并且将始终使用新事务。 Therefore anything happens to this new transaction will not affect the global transaction so that you can proceed with your further EJB calls. 因此,此新事务发生的任何事情都不会影响全局事务,因此您可以继续进行进一步的EJB调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在另一个实例中从事务方法调用 spring 非事务方法时,事务是否得到传播? - When calling a spring Non-Transactional method from a Transactional Method in another instance, does the transaction get propagated? 如何在相同和不同服务中调用@Transactional和non-Transactional方法时回滚事务? - How to rollback transaction on calling @Transactional and non-Transactional method in same and different Service? 从非事务方法调用的多个事务方法的传播级别 - Propagation level for multiple transaction methods called from a non-transactional method 如何从事务方法调用非事务方法 - How to call non-transactional methods from a Transactional method 是否可以将整个@Transactional类的一个方法标记为非事务性的 - Is it possible to mark one method of an entire @Transactional class as non-transactional 例外-非交易 - Exception - non-transactional 延迟加载在Hibernate的非事务类/方法中工作 - Lazy loading working in non-transactional class/method in Hibernate @Transactional propogation_new由父事务回滚 - @Transactional propogation_new being rolled back by parent Transaction 抛出异常后Spring事务未回滚 - Spring transaction not rolled back after an exception is thrown Spring Boot-从非事务性原因更新中校准事务性方法 - Spring Boot - caling transactional method from non-transactional cause update
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM