Spring+Mybatis嵌套事务,在子事务提交后查数据为空

Spring+Mybatis嵌套事务,在子事务提交后查数据为空

需求场景

public class BServiceImpl implements BSevice{
    @Autowired
    private ASevice aSevice;
    @Resource(name="transactionManager")  
    private DataSourceTransactionManager transactionManager;  

    @Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class)
    @Override
    public void methonA(Object o) {
        //做一些业务处理
        methonB(o);
        //做一些业务操作
        Object two = new Object();
        aSevice.qryByObject(two);

    }

    public void methonB(Object o) {
        //做一些处理
        aSevice.insert(o);
    }
}

public class A{
    @Autowired
    private ASevice aSevice;
    public void methonC(Object o) {
        aSevice.qryByObject(two);
    }
}

在BSercice的methonA中调用AService的insert()方法,之后再调用AService的qryByObject()方法查询刚插入的数据。A.methonC()可能是通过一些组件调用,如MQ。这样就会出现组件再调用methonC()时methonA的事务还没有提交,查询的数据为空。想到的解决方法是给methonB开启一个新事务手动提交。

public void methonB(Object o) {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();  
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。  
        TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态  
        try {
            aSevice.insert(o);
        } catch (Exception e) {
            transactionManager.rollback(status);  
            e.printStackTrace();
        }

    }

这样有出现新的问题,methonA()中调用aSevice.qryByObject()为空,应该是事务默认是可重复读级别,开启之后其他事务提交的数据也是查不到的。由于项目已经上线,客户比较赶。临时解决方法为给aSevice.qryByObject()也开启一个新事务。

@Transactional(propagation=Propagation.REQUIRES_NEW,readOnly=false,rollbackFor=Exception.class)
    @Override
    public Object qryByObject(Object o) {
        return null;
    }

注意propagation=Propagation.REQUIRES_NEW。

猜你喜欢

转载自blog.csdn.net/qq_34758074/article/details/79904052