简体   繁体   中英

Spring transaction not rolled back on Hibernate StaleObjectStateException

I have a scenario as below

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
}

My issue is, for a given flow i may have two request calling this method at same time. I expect methodC to throw exception for Optimistic locking failure and transaction to be rolled back.

My Expectation was:

Lets say i have two requests R1 and R2 R1 and R2 call methodA ->methodB (Starts a new transaction) ->methodC(transaction propogated) : both read same entity version, both make same changes and call merge -> methodC completes flow back to methodB -> methodB completes forcing transaction to commit-> transaction commit calls session.flush , gets run time exception for optimistic locking and is rolled back.

I do get the SOSE exception in method A , i can see it in my loggers but the transaction is committed and both the records are getting persisted.

Whats happening is as below: R1 and R2 call methodA ->methodB (Starts a new transaction) ->methodC(transaction propogated) : both read same entity version, both make same changes and call merge -> methodC completes flow back to methodB -> methodB completes forcing transaction to commit-> transaction commits -> throws run time exception for optimistic locking DOESN'T roll back and exception is caught by methodA.

If i explicitly throw an exception in methodC, transaction does get rolled back.

I am not sure why its not rolling back the transaction when the Optimisitc lock failure exception is thrown.

Please advise

Ok.. So i seems to have it working. Turns out the issue is with JTA provider. I was deploying the code on Tomee this will ensure Spring picks the provider from tomcat lib and it was using Gerenimo which seems to be not handling roll back. I pushed the same code on weblogic and used org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform as JTA provider, this seems to be working as expected. Will post if i get the reason why Gerenimo was not working or if there is something i am missing on it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM