[英]Spring / Hibernate @Transactional not flushing transaction if followed by a second @Transactional call
I have a weird behaviour in my Spring Boot App.我的 Spring 引导应用程序有一个奇怪的行为。
The app have the OpenSessionInView to false .该应用程序的OpenSessionInView为false 。
I have a Controller and a Service exposing 2 methods with annotation @Transactionnal .我有一个 Controller 和一个服务,它公开了两个带有注释@Transactionnal的方法。
Application.properties:应用程序属性:
spring.jpa.open-in-view=false
My service:我的服务:
@Service
public class MyService {
@Transactional(transactionManager = "myTx")
public void doA(Integer objectId) {
Object o = repo.findMyObject(objectId);
updateMyObject(o);
repo.save(o);
}
@Transactional(transactionManager = "myTx")
public void doB(Integer objectId) {
Object o = repo.findMyObject(objectId);
updateMyObjectDifferently(o);
repo.save(o);
}
}
My Controller (case 1):我的 Controller(案例 1):
@RequestMapping("/do/{myId}")
public String do(Model model, HttpServletRequest request) {
service.doA(myId);
service.doB(myId);
return "page";
}
With SQL in debug, I see that the SELECT queries are performed during the call to the service.在调试 SQL 的情况下,我看到在调用服务期间执行了 SELECT 查询。 But I see only 1 flush (several UPDATES) , and it's done when service.doB() is finished and the TransactionInterceptor around the method launch the method invokeWithinTransaction which is weird.
但是我只看到 1 个 flush (several UPDATES) ,并且它在 service.doB() 完成并且该方法周围的 TransactionInterceptor 启动方法 invokeWithinTransaction 时完成,这很奇怪。
As both method have @Transactional, I was hoping to see 2 flush : the first flush just at the end of service.doA() and a second flush at the end of service.doB().由于这两种方法都有@Transactional,我希望看到 2 次刷新:第一次刷新在 service.doA() 结束时,第二次在 service.doB() 结束时刷新。
What is more weird is that if I comment the second call, so更奇怪的是,如果我评论第二个电话,那么
My Controller (case 2):我的 Controller(案例 2):
@RequestMapping("/do/{myId}")
public String do(Model model, HttpServletRequest request) {
service.doA(myId);
//service.doB(myId);
return "page";
}
In case 1, it's like service.doA() knows that a second call will arrive just after on the same object, so it does not commit/flush the transaction and wait for the end of service.doB().在情况 1 中,就像 service.doA() 知道第二个调用将在同一个 object 之后到达,因此它不会提交/刷新事务并等待 service.doB() 结束。
Why do I see only 1 flush?为什么我只看到 1 次冲洗? Is it because both calls are on the some DB object?
是因为这两个调用都在某个 DB object 上吗?
I thought my knowledge of @Transactional were ok.我认为我对@Transactional 的了解还可以。 But now, I am lost.
但是现在,我迷路了。
Hibernate will detect if an object really is dirty and avoid sending an UPDATE
statement if it's not necessary. Hibernate 将检测 object 是否真的脏,如果没有必要,避免发送
UPDATE
语句。 I assume that your updateMyObject
is simply not changing the state of the entity with respect to the state it had initially when it was loaded.我假设您的
updateMyObject
根本没有改变实体的 state 相对于它最初加载时的 state。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.