Transaction Management in Spring Framework

In this article, I am going to give some information about transaction management in the spring framework, Before I start, I would like to touch on the keywords that we will mention a lot.

Transaction Management in Spring Framework

What are Commit and Rollback ?

When we have made any data manipulation, the databases are waiting for our approval in the “UPDATE” and “INSERT” transactions. The word we use to confirm the transactions is called “COMMIT” in the SQL language. Thanks to this word, we say that we want to confirm our insert or update operations. However, if we do not want the approve our transactions to be recorded in the database, then we provide cancellation of our transactions by using the word “ROLLBACK”.

What is Transaction?

The transaction is a process of managing one or more database manipulation together. It provides functionality for committing all changes at the same time or reverting all changes at the same time. Thanks to this data consistency are provided for modern applications.

Transaction Management

There are two types of transaction management that are pragmatic method and declarative method.

It is a method that contains the codes of starting and ending the transaction process and closing the open connections.

In Spring Framework, this can manage transactions by using Spring Container.

It’s done thanks to the @Transactional Annotation

  1. It is performed at the class or method level. The animation you wrote at the class level includes all the public methods in the class.
  2. A new transaction is initiated by the Spring Container when the Service Method is called. if The method is successfully completed, the changes are committed. But if any exception occurred during the method execution, all changes are reverted by the transectiıon.

Spring Boot Transaction Features

  1. Propagation
  2. ReadOnly
  3. TimeOut
  4. rollbackFor
  5. Isolation

There are 7 different Propagation types. When the service method is called, it is an enum class that determines whether the Transaction will be started or not, if there is an existing transaction, or whether it will continue or a new transaction is created.


This is a Default propagation type. If there is no active Transaction, it opens a new transaction. If there is an active Transaction, it participates in it.


If there is an active Transaction, it waits for the active one and opens a new transaction. Then When the required_new one is completed successfully, this committed the changes and continues the first Transaction. If a method that is marked as REQUIRED_NEW transaction is the first method, it behaves as REQUIRED one.

This is the first method that is marked as REQUIRED.

This is the second method that is marked as REQUIRED_NEW. Spring Container creates a new Transaction.


This is a valid rule in JDBC. It is using the savepoint technology that comes with JDBC 3.0. By using this, we define a savepoint that is the point which we want to roll back the changes until this point state.

When any exception occurs, data manipulations are reverted until this savepoint and the rest of the method continue to execute.

This is the first method that is marked as NESTED.

This is the second method that is marked as NESTED. Spring Container set a savepoint and if there is any exception occured, only second method’s changes are reverted but all changes are commited after first method completed successfully.


If there is Transaction in the service method, it will run, otherwise, it will run without Transaction.


If there is any active Transaction, it is suspended and the service method is executed without Transaction. After the method has been completed, the container resumes the client’s transaction.

It is recommended to use the NotSupported attribute for methods that don’t need transactions. Because transactions involve overhead, this attribute may improve performance.


For transactional logic with NEVER propagation, Spring throws an exception if there’s an active transaction:


If there is an active transaction, then it will be used. If there isn’t an active transaction, then Spring throws an exception:


When this property is set to true, a read-only transaction is opened. It can be used in transactions where no changes will be made to the database.


Thanks to this defining feature, when the method is not completed within the specified time, it performs the rollback operation.


The rollbackFor attribute is used for rollback the transaction for the given exception.

If we don’t provide any rollbackFor Exception or we don’t give rollbackFor as a parameter with @Transnational annotation, spring uses default rollback for RuntimeException/unchecked exception and Error.

When we write a method by using @Transactional annotation.

Spring Framework understand this like that

Spring does not provide default rollback for Checked exception and Exception or any custom exception that extends the Exception class.

It is possible to have multiple Exception class values for rollbackFor.

First One:

Second One:


Insulation is one of the common ACID properties like Atomicity, Consistency, Isolation, and Durability. Isolation describes how changes applied by concurrent processes are visible to each other.

Isolation level is used for preventing the side effects of zero or more concurrency in Transaction.

  • Dirty Read: it is used for reading uncommitted changes of a concurrent Transaction.
  • Nonrepeatable Read: it occurs when a transaction reads the same row twice. and every time it gets a different value. For example, suppose transaction X1 reads data AND there is a concurrency, another transaction X2 updates the same data and commits, if transaction X1 rereads the same data again, it will collect a different value.
  • Phantom read: it occurs when two same queries are executed, the rows that are retrieved by the two queries are different from each other. For example, transaction X1 collects a set of rows that is prepared by some search criteria. Then, Transaction X2 collects some new rows that match the search criteria for transaction X1. If transaction X1 executes the same search criteria again that reads the rows, it gets a different set of rows this time.

the isolation level of a transaction is defining by @Transactional(isolation = Isolation.). There are five types of it in Spring.



READ_COMMITTED prevents dirty reads. Dirty reads mean that uncommitted changes in concurrent transactions do not affect the other Transections. However, if a transaction commits its changes, the results could change by re-querying.

READ_COMMITTED is the default level with Postgres, SQL Server, and Oracle.


This isolation level allows concurrent access. This means that, while X1 Transaction is executing, if X2 changes any data without finishing the transaction yet, when X1 tries to get data that X2 is changing, it gets the new value of it although X2 does not commit the changes.

We can set the isolation level for a method or class:

Not: Postgres and Oracle databases does not support READ_UNCOMMITTED isolation.


REPEATABLE_READ, prevents dirty and non-repeatable reads. Therefore, it is not possible to effect uncommitted changes in concurrent transactions.

When we query for a row more than one time in a single transaction, the method does not return different results. However, When the execution of range-queries or query that is prepared by criteria, we may get newly added or removed rows.

When more than one Transaction trying to access a row and update it, the Lost update may occur. However, REPETABLE_READ does not allow reading a row at the same time. Therefore, it is not possible to face with Lost update.

This is the default level in Mysql. Oracle does not support it.


This is the highest isolation level. It prevents all side effects of concurrent transactions.

To Sum Up: this table is the summary of the things that we talk about isolation levels.

Difference of Isolation levels


Senior Software Engineer