1. Overview

Detecting transactions could be useful for audit purposes or for dealing with a complex code base where good transaction conventions weren’t implemented.

In this brief tutorial, we’ll go over a couple of ways to detect Spring transactions in our code.

2. Transaction Configuration

In order for transactions to work in Spring, transaction management must be enabled. Spring will enable transaction management by default if we’re using a Spring Boot project with spring-data-* or spring-tx dependencies. Otherwise, we’ll have to enable transactions and provide a transaction manager explicitly.

First, we need to add the @EnableTransactionManagement annotation to our @Configuration class. This enables Spring’s annotation-driven transaction management for our project.

Next, we must provide either a PlatformTransactionManager or a ReactiveTransactionManager bean. This bean requires a DataSource. We could choose to use a number of common libraries, such as those for H2 or MySQL. Our implementation doesn’t matter for this tutorial.

Once we enable transactions, we can use the @Transactional annotation to generate transactions.

3. Using TransactionSynchronizationManager

Spring has provided a class called TransactionSychronizationManager. Thankfully, this class has a static method that allows us to know whether we are in a transaction, called isActualTransactionActive().

To test this, let’s annotate a test method with @Transactional. We can assert that isActualTransactionActive() returns true:

@Test
@Transactional
public void givenTransactional_whenCheckingForActiveTransaction_thenReceiveTrue() {
    assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
}

Similarly, the test should assert that false is returned when we remove the @Transactional annotation:

@Test
public void givenNoTransactional_whenCheckingForActiveTransaction_thenReceiveFalse() {
    assertFalse(TransactionSynchronizationManager.isActualTransactionActive());
}

4. Using Spring Transaction Logging

Perhaps we don’t need to programmatically detect a transaction. If we would rather just see when a transaction happens in our application’s logs, we can enable Spring’s transaction logs in our properties file:

logging.level.org.springframework.transaction.interceptor = TRACE

Once we enable that logging level, transaction logs will start appearing:

2020-10-02 14:45:07,162 TRACE - Getting transaction for [com.Class.method]
2020-10-02 14:45:07,273 TRACE - Completing transaction for [com.Class.method]

These logs won’t offer very helpful information without any context. We can simply add some of our own logging and we should easily be able to see where transactions are happening in our Spring-managed code.

5. Conclusion

In this article, we saw how to check whether a Spring transaction is active. We learned how to programmatically detect transactions using the TransactionSynchronizationManager.isActualTransactionActive() method. We also discovered how to enable Spring’s internal transaction logging in case we want to see transactions in our logs.

As always, code examples can be found over on GitHub.