Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In SpringBoot, does Transactional annotation still rollbacks the transaction if I catch the DataAccessException

In SpringBoot using spring data jpa, default configurations (not changing anything), if in my service layer I call the saveAll method of a given repository which is annotated with @Repository, and I have a catch clause that catches DataAccessException which I understand is the one that covers all the possible exceptions that could go wrong with the database, will the rollback still be triggered thanks to the @Transactional annotation?

For example:

Repository:

@Repository
public interface BookRepository extends JpaRepository<Book, Integer> {

}

Service:

@Service
public class BookService {

    private final BookRepository bookRepository;

    public BookService(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }

    public void saveAllBooks(List<Book> books) {
        try {
            bookRepository.saveAll(books);
        } catch (DataAccessException e) {
            // notify external service about failure
            // log exception
        }
    }

}

If I do this, the rollback will still happen or do I need to rethrow the exception? I need to guarantee the atomicity of this kind of transaction, save all the books or not save any of the books. Thanks in advance :)

like image 992
BugsOverflow Avatar asked Oct 15 '25 08:10

BugsOverflow


2 Answers

First thing what need a clarification. As you are using Spring Data JPA then the annotation @Repository is irrelevant and will be ignored. Spring will instead use the EnableJpaRepositories and configure a proxy of SimpleJPARepository for every interface which extends the JPARepository. What your BookRepository does. In consequence all methods of this repository will be transactional.

All exceptions thrown in these methods will be translated by Spring and:

  • any unchecked exception (like DataAccessException, IndexOutOfBoundsException) will trigger rollback of the transaction
  • any checked exception (like SQLException) will NOT trigger rollback

This will happen independent and before the try/catch logic.

like image 161
Mar-Z Avatar answered Oct 16 '25 22:10

Mar-Z


saveAll() method is implemented in the SimpleJpaRepository class.

    @Transactional
    @Override
    public <S extends T> List<S> saveAll(Iterable<S> entities) {

    }

It has @Transactional annotation. Your service method doesn't have @Transactional annotation. So it means the rollback will still happen, even you catch an exception. You don't need to rethrow an exception in such case.

Otherwise if you put @Transactional to your saveAllBooks() method, rollback will not happen. The reason that the annotation from saveAllBooks() cancel the annotation from saveAll().

    @Transactional
    public void saveAllBooks(List<Book> books) {
        try {
            bookRepository.saveAll(books);
        } catch (DataAccessException e) {
            // notify external service about failure
            // log exception
        }
    }
like image 45
v.ladynev Avatar answered Oct 16 '25 21:10

v.ladynev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!