As you see the below code, I have handled the runtime exception and written some code to prevent this still transaction is rolled back to my surprise.
I have read up few answers on this similar question but still I end up getting the issue. Need clear explanation and solutions to tackle the issue please.
[Code Explanation]
In the below code, I am trying to save an obj of type Event(Version is unique key in my Events table) where it gives me unique constraint violation exception if already the same version is found. This behaviour of having an already existing version is not avoidable for my use case, however I can increase the version and reattempt it.
[Problem]
However what I observed is when it finds an existing version it goes to the catch block, it does increment the version and try reattempting and finally it becomes successful. method m2() is executed ultimately, so is m3() and finally m1().
But instead of getting a 201 response I am getting 500 error with message transaction is rolled-back.
What are the ways of handling this? thanks.
[Code]
@Transactional
void m1(Event event){
//DB write operation
m2(event);
//DB write operation
m3();
}
@Transactional
void m2(Event obj){
boolean success = false;
while(!success){
try{
eventRepo.save(event);
success = true;
} catch(UniqueConstraintViolationException e){
event.setVersion(++event.getVersion());
}
}
}
In your case, even though you're catching the
UniqueConstraintViolationExceptionand reattempting the save operation, the transaction isn't committed if an exception was thrown, and that's why you're seeing a500 error.To handle this situation you can use a
programmatic transactionapproach. Here's how you can do it:This way, you can
handle exceptionsand retries within the scope of your transaction without affecting the outer transaction andcausing a rollback. Try it and let me know if you still face any issue.