Spring Data JPA - transactions

Reading material

  1. https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#transactions
  2. https://spring.io/guides/gs/managing-transactions/
  3. https://www.baeldung.com/transaction-configuration-with-jpa-and-spring

@EnableTransactionManagement in Spring Boot

  1. https://stackoverflow.com/questions/40724100/enabletransactionmanagement-in-spring-boot
  2. https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html
  3. https://www.geeksforgeeks.org/spring-boot-transaction-management-using-transactional-annotation/

ACID

The acronym for the four properties guaranteed by transactions: atomicity, consistency, isolation, and durability.

How to implement transactions using Spring JPA?

Basically, there are two distinct ways to configure Transactions, each with its own advantages.

  1. annotations
  2. AOP

Configure Transactions

@EnableTransactionManagement

If we’re using a Spring Boot project and have a spring-data-* or spring-tx dependencies on the classpath, then transaction management will be enabled by default.

If not, we can enable it using @EnableTransactionManagement annotation

Spring 3.1 introduces the @EnableTransactionManagement annotation that we can use in a @Configuration class to enable transactional support:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{
...

@Transactional

The @Transactional Annotation

With transactions configured, we can now annotate a bean with @Transactional either at the class or method level:

@Service
@Transactional
public class FooService {
    //...
}

The annotation supports further configuration as well:

  1. the Propagation Type of the transaction
  2. the Isolation Level of the transaction
  3. a Timeout for the operation wrapped by the transaction
  4. a readOnly flag – a hint for the persistence provider that the transaction should be read only
  5. the Rollback rules for the transaction

Note that by default, rollback happens for runtime, unchecked exceptions only. The checked exception does not trigger a rollback of the transaction. We can, of course, configure this behavior with the rollbackFor and noRollbackFor annotation parameters.

Potential Pitfalls

Transactions and Proxies

At a high level, Spring creates proxies for all the classes annotated with @Transactional, either on the class or on any of the methods. The proxy allows the framework to inject transactional logic before and after the running method, mainly for starting and committing the transaction.

What’s important to keep in mind is that, if the transactional bean is implementing an interface, by default the proxy will be a Java Dynamic Proxy. This means that only external method calls that come in through the proxy will be intercepted. Any self-invocation calls will not start any transaction, even if the method has the @Transactional annotation.

Another caveat of using proxies is that only public methods should be annotated with @Transactional. Methods of any other visibilities will simply ignore the annotation silently as these are not proxied.

Tags

  1. Proxies in Spring