事务回滚上一个事务

Transaction rollbacked previous transaction

我在 Spring.

中的交易有这种奇怪的行为

我有两个 classes:

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

@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
    }
}

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

@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,也不会调用我的方法 doGenericStuff()。但是,ServiceClass 会调用 CommonBusinessClass,后者又会调用 ServiceClass。也许这是糟糕的设计,也许是它不起作用的原因,但这就是我目前所拥有的。

ServiceClass 中的方法不是事务性的(因此注释),doGenericBusinessStuff() 是(Propagation.MANDATORY)。

新要求是,如果 secondOperation() 失败(和回滚),则应提交 firstOperation()。所以我为 firstOperation()secondOperation() 添加了 @Transactional (评论中的那些)。我期望它能正常工作(secondOperation() 中的异常不会回滚在 firstOperation() 中所做的事情),但它没有。但是,如果我删除 doGenericBusinessStuff() 上的 @Transactional,它会起作用。

这种行为是正常的,还是在我的实际应用程序中有其他我没有放在这里的东西在起作用(因为我简化了它)?为什么新创建的交易会以任何方式相互链接?对可能发生的事情有什么想法吗?

提前致谢。

您需要了解交易的上下文。如果您将方法标记为事务性的,则意味着该方法内的每个操作都将被视为一件事。如果一切正常,则提交事务,但如果出现问题,则回滚整个事务。

在你的情况下你有:

  @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 中的所有操作都将被取消。

编辑:REQUIRES_NEW 在某些情况下可能不起作用,例如,如果您使用 JtaTransactionManager:

NOTE: Actual transaction suspension will not work out-of-the-box on all transaction managers. This in particular applies to JtaTransactionManager

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