我的情况如下
methodA(){
try{
objB.methodB();
}
catch(Exception ex){
log(exception caught);
}
@Transactional(value = "txManager", propagation = Propagation.REQUIRES_NEW,rollbackFor={Exception.class, StaleObjectStateException.class})
methodB(){
methodC();
}
@Transactional(value = "txManager", propagation = Propagation.REQUIRED, rollbackFor = {Exception.class,StaleObjectStateException.class})
methodC(){
/*Some logic that throws HOLF/SOSE exception. Essentially calling merge on entity that has @Version enabled
}
我的问题是,对于给定的流程,我可能有两个请求同时调用此方法。我希望methodC为乐观锁定失败抛出异常并回滚事务。
我的期望是:
假设我有两个请求R1和R2 R1和R2调用方法A - >方法B(启动新事务) - >方法C(事务传播):两者都读取相同的实体版本,都进行相同的更改并调用merge - > methodC完成流程回到methodB - > methodB完成强制事务提交 - >;事务提交调用session.flush,获取乐观锁定的运行时异常并回滚。
我确实在方法A中得到了SOSE异常,我可以在记录器中看到它,但事务已经提交,并且两个记录都被保留了。
发生的事情如下: R1和R2调用方法A - >方法B(启动新事务) - >方法C(事务传播):两者都读取相同的实体版本,都进行相同的更改并调用merge - > methodC完成流程回到methodB - > methodB完成强制事务提交 - >;交易提交 - >抛出运行时异常以进行乐观锁定不回滚且异常被方法A捕获。
如果我在methodC中显式抛出异常,则会回滚事务。
我不确定为什么抛出Optimisitc锁定失败异常时它不会回滚事务。
请告知
答案 0 :(得分:0)
好的..所以我好像有效。事实证明,问题在于JTA提供商。我在Tomee上部署代码,这将确保Spring从tomcat lib中选择提供程序,并且它正在使用Gerenimo,它似乎没有处理回滚。 我在weblogic上推送了相同的代码,并使用org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform作为JTA提供程序,这似乎按预期工作。 如果我明白为什么Gerenimo没有工作或者我有什么东西在它上面就会发布。