Deep understanding of Spring transaction Principles

Source: Internet
Author: User
Tags savepoint

First, the basic principle of business

The essence of spring transaction is that the database supports the transaction, and without the transaction support of the database, spring cannot provide the transaction function. For a pure JDBC operations database, to use transactions, you can follow these steps:

Get connection Connection con = drivermanager.getconnection ()

Open transaction Con.setautocommit (True/false);

Executing crud


Close connection conn.close ();

With the transaction management features of spring, we can no longer write the code for steps 2 and 4, but it is done automatically by SPIRNG. So how does spring open and close transactions before and after the CRUD we write? To solve this problem, we can understand the principle of the implementation of Spring's transaction management as a whole. The following is a brief introduction to the annotated method as an example

The config file turns on the annotation driver and @transactional the identifier on the relevant classes and methods through annotations.

Spring will parse the generated bean when it is started, and it will look at the classes and methods that have the relevant annotations, generate proxies for those classes and methods, and inject the relevant configuration according to the relevant parameters of @transaction. This allows the related transaction to be disposed of in the proxy (the normal commit transaction is turned on, and the transaction is rolled out unexpectedly).

The transaction commit and rollback of the true database layer is implemented by Binlog or redo log.

Second, the propagation properties of Spring transactions

The propagation attribute of the so-called spring transaction is the definition of how spring should handle the behavior of these transactions when there are multiple transactions at the same time. These properties are defined in Transactiondefinition, and the specific constants are explained in the following table:

Constant name constant explanation

Propagation_required supports the current transaction and creates a new transaction if there is no current transaction. This is the most common choice and is also the propagation of Spring's default transactions.

Propagation_requires_new a new transaction, suspending the current transaction if a transaction is currently present. The newly created transaction will have no relation to the suspended transaction, is two separate transactions, after the outer transaction fails rollback, cannot roll back the results of the inner transaction execution, the inner transaction fails to throw an exception, the outer transaction is caught, or the rollback operation can not be processed

Propagation_supports supports the current transaction and is executed in a non-transactional manner if no transaction is currently in use.

The propagation_mandatory supports the current transaction and throws an exception if there is no current transaction.

The propagation_not_supported executes the operation in a non-transactional manner, suspending the current transaction if a transaction is currently present.

The propagation_never is executed in a non-transactional manner and throws an exception if a transaction is currently present.

propagation_nested If an active transaction exists, it is run in a nested transaction. If there is no active transaction, it is performed by the required property. It uses a separate transaction that has multiple savepoint that can be rolled back. The rollback of internal transactions does not affect external transactions. It only works with the Datasourcetransactionmanager transaction manager.

Third, database isolation level

Issues caused by value of isolation level isolation level

Read-uncommitted0 causes dirty Reads

Read-committed1 avoid dirty reads, allow non-repeatable reads and Phantom reads

Repeatable-read2 avoid dirty reading, non-repeatable read, allow Phantom reading

Serializable3 serialization, transactions can only be executed one at a time, avoiding dirty reads, non-repeatable reads, and Phantom reads. Slow execution and careful use

Dirty read: One transaction has added or deleted data, but uncommitted, another transaction can read to uncommitted data. If the first transaction is rolled back at this time, then the second transaction is enrolled in dirty data.

Non-repeatable reads: Two reads occurred in a transaction, between the first read operation and the second operation, and the other transaction modifies the data, at which time two reads are inconsistent.

Phantom read: The first transaction makes bulk modifications to a range of data, and the second transaction adds one data to that range, when the first transaction loses the modification to the new data.


The higher the isolation level, the greater the integrity and consistency of the data, but also the greater the impact on concurrency performance.

Most of the database default isolation levels are Read commited, such as SQL Server, Oracle

The default isolation level for a few databases is: repeatable Read for example: MySQL InnoDB

Iv. isolation levels in spring

Constant interpretation

Isolation_default This is a platfromtransactionmanager default isolation level, which uses the default transaction isolation level of the database. The other four correspond to the isolation level of JDBC.

Isolation_read_uncommitted This is the lowest isolation level of a transaction, which allows another transaction to see the uncommitted data for this transaction. This isolation level produces dirty reads, non-repeatable reads, and Phantom reads.

Isolation_read_committed guarantees that a transaction modified data is committed before it can be read by another transaction. Another transaction cannot read uncommitted data for the transaction.

Isolation_repeatable_read This transaction isolation level prevents dirty reads and cannot be read repeatedly. However, Phantom reads may occur.

Isolation_serializable This is the most cost-effective, but most reliable, transaction isolation level. Transactions are processed for sequential execution.

V. Nesting of transactions

Through the foundation of the theoretical knowledge above, we generally know some properties and characteristics of database transactions and spring transactions, and then we can understand the mechanism of spring transaction propagation by analyzing some nested transaction scenarios.

Suppose that method a () of the outer transaction service A calls the method B () of the Inner Service B ()

Propagation_required (Spring Default)

If the transaction level of SERVICEB.METHODB () is defined as propagation_required, then the Servicea.methoda () is executed when spring has a transaction, and Serviceb.methodb () is called. Serviceb.methodb () sees that he is already running inside the Servicea.methoda () transaction, and no new transactions are made.

If Serviceb.methodb () runs and discovers that he is not in the transaction, he assigns himself a transaction.

In this way, the transaction is rolled back when an exception occurs in Servicea.methoda () or anywhere within the SERVICEB.METHODB ().


For example, we design a transaction level of Servicea.methoda () with a transaction level of Propagation_required,serviceb.methodb () of propagation_requires_new.

Then when executing to SERVICEB.METHODB (), the transaction where Servicea.methoda () is suspended, Serviceb.methodb () will start a new transaction, waiting for the transaction of Serviceb.methodb () to complete , it will continue to execute.

The difference between his affairs and Propagation_required is the degree of rollback of the transaction. Because Serviceb.methodb () is a new transaction, there are two different transactions. If Serviceb.methodb () has been committed, then Servicea.methoda () Failure rollback, SERVICEB.METHODB () is not rolled back. If Serviceb.methodb () fails to roll back, if he throws an exception that is caught by Servicea.methoda (), the Servicea.methoda () transaction can still be committed (mainly seeing that the exception thrown by B is not a rollback exception).


Assuming that the transaction level for Serviceb.methodb () is propagation_supports, then when executing to SERVICEB.METHODB (), if Servicea.methoda () is found to have a transaction open, The current transaction is added, and if Servicea.methoda () is found to have no transaction turned on, it does not open the transaction itself. At such times, the transactional of the internal method is entirely dependent on the outermost transaction.


Now the situation becomes more complicated, and the transaction properties of Serviceb.methodb () are configured as propagation_nested, and how will the two work together? Serviceb#methodb if rollback, then the internal transaction (that is, serviceb#methodb) is rolled back to the savepoint before it executes, and the external transaction (that is, Servicea#methoda) can be handled in the following two ways:

A, catch exception, execute the exception branching logic

Voidmethoda () {try{serviceb.methodb ();    }catch (someexception) {//Perform other business, such as SERVICEC.METHODC ();} }

This is also the most valuable place for a nested transaction, which has the effect of branching, if Serviceb.methodb fails, then SERVICEC.METHODC () is executed, and Serviceb.methodb is rolled back to the SavePoint, so there is no dirty data (equivalent to this method never executed), this feature can be used in some special business, and propagation_required and propagation_requires_new have no way to do this.

b, the external transaction rollback/Commit code does not make any changes, then if the internal transaction (SERVICEB#METHODB) rollback, then the first serviceb.methodb rollback to the savepoint before it executes (in any case), the external transaction (that is, Servicea#methoda) will decide whether to commit or rollback according to the specific configuration

The other three kinds of transactional propagation properties are basically not available, and no analysis is done here.

Vi. Summary

For places where transactions need to be used in a project, I recommend that developers use the spring Transactioncallback interface to implement transactions, do not blindly use the spring transaction annotations, and if you must use annotations, It is important to have a detailed understanding of the propagation mechanism and isolation level of the spring transaction, otherwise it is likely that unexpected results will occur.

Deep understanding of Spring transaction Principles

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.