Consider I have following spring beans
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
}
}
The cacheable aspect has a higher order
The problem with this code is that it will start two transactions (and take two connections from the pool) in case of cache-miss in both services. Can I configure Spring to use the same transaction in this use case? I.E. propagate the transaction from ServiceA to the CompositeService and after that down to ServiceB?
I cannot set the CompositeService as transactional because I do not want to start a transaction (and borrow a connection from pool) in case of cache-hit both in ServiceA and ServiceB
Spring will only propagate a transaction if everything is under the same transaction. So the short answer is that you should annotate your CompositeService
with @Transactional
.
@Service
public class CompositeService {
@Transactional
public ResultBean compositeMethod() {
ResultBean result = new ResultBean();
result.setA(serviceA.getA());
result.setB(serviceB.getB());
return result;
}
}
Generally this is fast enough as it only does a checkout from the underlying connection pool. However if you experience latency or don't always need a connection you can wrap your actual DataSource
in a LazyConnectionDataSourceProxy
. This will obtain a Connection
when first needed.
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加