事务回滚上一个事务

时间:2016-10-05 14:17:18

标签: java spring transactions jta

我对Spring中的事务有这种奇怪的行为。

我有两个班级:

doGenericServiceStuff首先调用的服务类(由另一个已拥有事务的对象调用):

SYSTEM

然后调用一些ServiceClass的CommonBusinessClass'方法:

@Service("myService")
public class ServiceClass {

    public void doGenericServiceStuff(Object someBean){
        BusinessI business = BusinessFactory.getBusinessForObject(someBean); //Here, returns the commonBusinessClass bean 
        business.doGenericBusinessStuff(someBean);
    }

    /*@Transactional (readOnly=false, rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)*/
    public void firstOperation(Object o){
        //multiple database insert and stuff
    }

    /*@Transactional (readOnly=false, rollbackFor=Exception.class, propagation=Propagation.REQUIRES_NEW)*/
    public void secondOperation(Object o){
        //also multiple database insert and stuff
    }
}

免责声明:显然,我不会像这样操纵@Bean("commonBusinessClass") public class CommonBusinessClass implements BusinessI{ @Autowired @Qualifier("myService") protected ServiceClass = null; @Transactional(rollBackFor=Exception.class, Propagation=Propagation.MANDATORY) public Object doGenericBusinessStuff(Object o){ service.firstOperation(o); service.secondOpertion(o); //There can be stuff here in other BusinessClass return o; } } 而我也不会调用我的方法Objects。但是,ServiceClass会调用CommonBusinessClass,而CommonBusinessClass又调用ServiceClass。也许这是糟糕的设计,也许是它无法正常工作的原因,但这就是我现在所拥有的。

doGenericStuff()中的方法不是Transactional(因此是注释),而ServiceClass是(doGenericBusinessStuff())。

新要求是,如果Propagation.MANDATORY失败(并且回滚)secondOperation()应该被提交。所以我为firstOperation()@Transactional(评论中的那些)添加了firstOperation()。我期待它能够正常工作(secondOperation()中的例外不会回滚secondOperation()中已经完成的事情),但事实并非如此。但是,如果我删除了firstOperation()上的@Transactional,那就可以了。

这种行为是否正常,或者在我的实际应用程序中还有其他东西在我放在这里(因为我简化了)?为什么新创建的交易会以任何方式相互关联?关于可能发生什么的任何想法?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您需要了解交易的背景。如果将方法标记为事务性,则意味着该方法中的每个操作都将被视为一个操作。如果一切正常,那么事务就会被提交,但是如果出现问题,那么整个事务就会被回滚。

在你的情况下,你有:

  @Transactional(rollBackFor=Exception.class, Propagation=Propagation.MANDATORY)
    public Object doGenericBusinessStuff(Object o){
        service.firstOperation(o);
        service.secondOpertion(o);
        //There can be stuff here in other BusinessClass
        return o;
    }

因此,如果service.firstOperation(o)失败,那么整个事务将被回滚,而service.secondOpertion(o)则相同。如果service.secondOpertion(o)失败,doGenericBusinessStuff内的所有操作都将被收回。

编辑:如果您使用JtaTransactionManager,则REQUIRES_NEW在某些情况下可能无效:

  

注意:实际的交易暂停不会开箱即用   所有交易经理。这尤其适用于   的JtaTransactionManager

来自http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/annotation/Propagation.html