将spring事务传播给兄弟调用

时间:2015-01-20 06:08:36

标签: java spring transactions

考虑我有跟随春豆

CompositeService

@Service
public class CompositeService {

    @Resource
    private ServiceA serviceA;

    @Resource
    private ServiceB serviceB;

    public ResultBean compositeMethod() {
        ResultBean result = new ResultBean();
        result.setA(serviceA.getA());
        result.setB(serviceB.getB());
        return result;
    }

}

ServiceA

@Service
public class ServiceA {

    @Transactional
    @Cacheable
    A getA() {
        // calls DAO layer and makes a query to the database
    }

}

ServiceB

@Service
public class ServiceB {

    @Transactional
    @Cacheable
    B getB() {
        // calls DAO layer and makes a query to the database
    }

}

可缓存方面具有更高的顺序

此代码的问题在于,如果两个服务都出现缓存未命中,它将启动两个事务(并从池中获取两个连接)。 我可以将Spring配置为在此用例中使用相同的事务吗? I.E.将事务从 ServiceA 传播到 CompositeService ,之后传递到 ServiceB

我无法将 CompositeService 设置为事务性,因为我不希望在 ServiceA 中遇到缓存命中时启动事务(并从池中借用连接)和 ServiceB

2 个答案:

答案 0 :(得分:1)

如果所有内容都在同一个事务中,Spring将只传播一个事务。简而言之,您应该使用CompositeService注释@Transactional

@Service
public class CompositeService {

    @Transactional
    public ResultBean compositeMethod() {
        ResultBean result = new ResultBean();
        result.setA(serviceA.getA());
        result.setB(serviceB.getB());
        return result;
    }
}

通常这很快,因为它只从底层连接池进行结账。但是,如果您遇到延迟或者并不总是需要连接,则可以将实际的DataSource包装在LazyConnectionDataSourceProxy中。这将在首次需要时获得Connection

答案 1 :(得分:0)

您可以做的是您也可以使用@Transactional注释 compositeMethod 。事务的默认传播级别设置为Required

  

支持当前事务,如果不存在则创建一个新事务。

因此,尽管它不完全是您所要求的,但事务划分以compositeMethod开头,但它应该是您想要的语义。