将 spring 事务传播到同级调用

Propagate spring transaction to sibling call

考虑一下我有以下 spring 个豆子

复合服务:

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

}

服务A:

@Service
public class ServiceA {

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

}

服务 B:

@Service
public class ServiceB {

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

}

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

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

我无法将 CompositeService 设置为事务性的,因为我不想在缓存命中的情况下启动事务(并从池中借用连接) 服务A服务B

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

Support a current transaction, create a new one if none exists.

所以即使它不完全是你问的那样,事务划分是从 compositeMethod 开始的,但它应该正是你想要的语义。

Spring 仅当所有内容都在同一事务下时才会传播事务。所以简短的回答是你应该用 @Transactional.

注释你的 CompositeService
@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