I Was Scolded by the Boss Because I Didn’t Add rollbackfor = Exception.Class to @Transactional
内容转载于 https://medium.com/javarevisited/i-was-scolded-by-the-boss-because-i-didnt-add-rollbackfor-exception-class-to-transactional-68cbeaea28a0
What Happens If the @transactional Annotation Does Not Add Rollbackfor = Exception.Class?
First prepare a piece of data in Mysql
Start testing
Let’s test @Transactional
first, everyone knows that 2/0
will throw an exception. The code is as follows.
@Transactional
public Response<Void> updateMedium(UserVO userVO){
UserDomain userDomain = this.getIfPresent(userVO.getId());
userDomain.setDeleted(userVO.getDeleted());
UserDomain saved = userRepository.save(userDomain);
int a = 2 / 0;
return Response.success();
}
Execute the test UserDomain saved
, deleted=0
indicates that the update is successful, don’t worry, let’s continue to breakpoint and go below.
As expected, an error was reported when int a = 2 / 0
, and a java.lang.ArithmeticException: /by zero appeared
That the exception class ArithmeticException
inherits RuntimeException
The exception that @Transactional
rolls back by default is RuntimeException
We click into the RuntimeException
class to find out. We find that RuntimeException
inherits Exception
and all exception classes basically inherit RuntimeException
including the java.lang.ArithmeticException
exception just above.
So as long as the exception thrown by the subclasses of RuntimeException
and RuntimeException @Transactional
can be rolled back.
At this time, let’s see if the value of the database has been modified successfully. Obviously, the data has been rolled back.
Let’s try adding an exception to @Transactional’s
code and see what happens? Code show as below.
@Transactional
public Response<Void> updateMedium(UserVO userVO) throws Exception {
UserDomain userDomain = this.getIfPresent(userVO.getId());
userDomain.setDeleted(userVO.getDeleted());
userDomain.setPassword(userVO.getPassword());
userDomain.setUsername(userVO.getUsername());
userDomain.setCreateTime(new Date());
UserDomain saved = userRepository.save(userDomain);
try {
int a = 2 / 0;
} catch (Exception e) {
throw new Exception();
}
return Response.success();
}
We directly use try catch to catch exceptions and then custom throw Exception
exceptions in catch.
The exception thrown directly is the java.lang.Exception
exception we specified. Let’s take a look at the database.
The database deleted
has been updated to 0, indicating that @Transactional
cannot roll back Exception
Finally
@Transactional
can only rollback exceptions thrown by subclasses of RuntimeException and RuntimeException, and cannot rollback Exception
exceptions.
It is recommended that everyone use @Transactional(rollbackFor = Exception.class)
scenarios
- If you need to support rollback Exception
- If it is to add, delete or modify here
Some invalid scenarios of @Transactional(rollbackFor = Exception.class)
- Not modified with public
- The try catch catches the exception (no exception is thrown manually in the catch)
- No
@Service
is added (that is, it is not managed by Spring)
Thanks for reading. I am looking forward to your following and reading more high-quality articles.
内容转载于 https://medium.com/javarevisited/i-was-scolded-by-the-boss-because-i-didnt-add-rollbackfor-exception-class-to-transactional-68cbeaea28a0