Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I continue a transaction in Spring Boot with PostgreSQL after an Exception occured?

I created a service method that creates user accounts. If creation fails because the given e-mail-address is already in our database, I want to send the user an e-mail saying they are already registered:

@Transactional(noRollbackFor=DuplicateEmailException.class)
void registerUser(User user) {
   try {
      userRepository.create(user);
   catch(DuplicateEmailException e) {
      User registeredUser = userRepository.findByEmail(user.getEmail());
      mailService.sendAlreadyRegisteredEmail(registeredUser);
   }
}

This does not work. Although I marked the DuplicateEmailExcepetion as "no rollback", the second SQL query (findByEmail) still fails because the transaction was aborted.

What am I doing wrong?

There is no @Transactional annotation on the repository.

like image 263
Bastian Voigt Avatar asked May 09 '17 08:05

Bastian Voigt


People also ask

Which type of exceptions does spring Transaction Manager automatically mark for rollback?

Note however that the Spring Framework's transaction infrastructure code will, by default, only mark a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException. (Errors will also - by default - result in a rollback.)

How is transaction maintained in spring boot?

Spring Boot implicitly creates a proxy for the transaction annotated methods. So for such methods the proxy acts like a wrapper which takes care of creating a transaction at the beginning of the method call and committing the transaction after the method is executed.

What is @transactional rollbackFor exception class?

@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.


1 Answers

That's not a problem with Spring / JDBC or your code, the problem is with the underlying database. For example, when you are using the Postgres if any statement fails in a transaction all the subsequent statements will fail with current transaction is aborted.

For example executing the following statements on your Postgres:

> start a transaction
> DROP SEQUENCE BLA_BLA_BLA;
> Error while executing the query; ERROR: sequence "BLA_BLA_BLA" does not exist"
> SELECT * FROM USERS;
> ERROR: current transaction is aborted, commands ignored until end of transaction block

Still the SELECT and subsequent statements are expected to succeed against MySQL, Oracle and SQL Server

like image 166
Babl Avatar answered Sep 30 '22 13:09

Babl