Writing in the front

Glacier, can you write an article about Spring transactions? I: ok, arrangement top! So what are you waiting for? Let’s go!

The fundamentals of transactions

The essence of Spring transactions is the transaction support of the database. Without the transaction support of the database, Spring cannot provide transaction functionality. For pure JDBC-operated databases, to use transactions, follow these steps:

  1. Get connected Connection con = DriverManager. GetConnection ()
  2. Enable transaction con.setAutoCommit(true/false);
  3. Perform the CRUD
  4. Commit/rollback transaction con.mit ()/con.rollback();
  5. Conn.close ();

Using Spring’s transaction management capabilities, we can stop writing the code for steps 2 and 4 and let Spirng do it automatically. 
 So how does Spring start and close transactions before and after the CRUD we wrote? Solve this problem, and you can understand Spring’s transaction management implementation as a whole. The following is a brief introduction of the annotation method as an example

  1. The config file turns on the annotation driver, which identifies the Transactional classes and methods with the @transactional annotation.
  2. Spring will parse and generate the beans at startup, look at the classes and methods that have the annotations, generate a proxy for those classes and methods, and configure and inject them according to @Transaction parameters. This will dispose of the Transaction in the proxy for us. Exception rollback transaction).
  3. The real database layer commits and rolls back transactions through binlog or redo log.

Spring transaction propagation properties

The propagation properties of Spring transactions define the behavior of how Spring should handle multiple simultaneous transactions. These properties are defined in TransactionDefinition, and the specific constants are explained in the following table:

The name of the constant Constant interpretation
PROPAGATION_REQUIRED Supports current transactions and creates a new one if there are none. This is the most common choice and is the propagation of transactions by Spring’s default.
PROPAGATION_REQUIRES_NEW Create a new transaction and suspend the current transaction if one exists. The newly created transaction will have no relationship with the suspended transaction, and is two independent transactions. After the outer transaction fails to roll back, the result of the inner transaction execution cannot be rolled back. The inner transaction fails to throw an exception, and the outer transaction is captured, and the rollback operation can be not processed
PROPAGATION_SUPPORTS Current transactions are supported, and non-transactionally executed if there are none.
PROPAGATION_MANDATORY Supports current transactions and throws an exception if there are none.
PROPAGATION_NOT_SUPPORTED Performs the operation nontransactionally, suspending the current transaction if one exists.
PROPAGATION_NEVER Executes nontransactionally, throwing an exception if a transaction currently exists.
PROPAGATION_NESTED If an active transaction exists, it runs in a nested transaction. If there are no active transactions, the REQUIRED attribute is executed. It uses a single transaction that has multiple savepoints that can be rolled back. A rollback of an internal transaction has no effect on an external transaction. It is only right DataSourceTransactionManager transaction manager work.

Database isolation level

Isolation level Value of the isolation level Resulting problems
Read-Uncommitted 0 Lead to dirty reads
Read-Committed 1 Avoid dirty reads and allow unrepeatable and phantom reads
Repeatable-Read 2 Avoid dirty read, do not repeat read, allow magic read
Serializable 3 Serialized read, transactions can only be executed one by one, avoiding dirty read, unrepeatable read, phantom read. The execution efficiency is slow and the use is cautious

Dirty read: one transaction adds, deletes, and modifies data but does not commit it, and another transaction can read data that has not been committed. If the first transaction rolls back at this point, the second transaction reads dirty data.

Non-repeatable reads: two reads occur in one transaction. Between the first read and the second read, another transaction modifies the data. In this case, the two reads are inconsistent.

Phantom read: the first transaction makes batch changes to a certain range of data, and the second transaction adds a single piece of data to the range, so the first transaction loses its changes to the new data.

Conclusion:

A higher isolation level ensures data integrity and consistency, but has a greater impact on concurrency performance.

The default isolation level for most databases is Read Commited, such as SqlServer and Oracle

For a few databases, the default isolation level is Repeatable Read. For example, MySQL InnoDB

Isolation levels in Spring

constant explain
ISOLATION_DEFAULT This is a PlatfromTransactionManager default isolation level, using the database default transaction isolation level. The other four correspond to JDBC isolation levels.
ISOLATION_READ_UNCOMMITTED This is the lowest isolation level for a transaction and allows another transaction to see the uncommitted data of that transaction. This isolation level produces dirty reads, non-repeatable reads, and phantom reads.
ISOLATION_READ_COMMITTED Ensure that data modified by one transaction is committed before it can be read by another transaction. Another transaction cannot read uncommitted data from that transaction.
ISOLATION_REPEATABLE_READ This transaction isolation level prevents dirty, non-repeatable reads. But illusionary reading can occur.
ISOLATION_SERIALIZABLE This is the most expensive but reliable transaction isolation level. Transactions are processed for sequential execution.

Fifth, the nesting of transactions

Based on the above theoretical knowledge, we have a general understanding of some properties and characteristics of database transactions and Spring transactions. Next, we will analyze some scenarios of nested transactions to further understand the mechanism of Spring transaction propagation.

Suppose Method A() of outer transaction Service A calls Method B() of inner transaction Service B.

PROPAGATION_REQUIRED (default) spring

If the transaction level of serviceb.methodb () is defined as PROPAGATION_REQUIRED, then spring already executes a transaction when servicea.methoda () is invoked, The serviceb.methodb () sees that it is already running inside the servicea.methoda () transaction and does not start any new transactions.

If serviceb.methodb () is not in a transaction when it runs, it allocates a transaction to itself.

This way, if an exception occurs anywhere within Servicea.methoda () or serviceb.methodb (), the transaction will be rolled back.

PROPAGATION_REQUIRES_NEW

For example, we design the transaction level for Servicea.methoda () to be PROPAGATION_REQUIRED and for Serviceb.methodb () to be PROPAGATION_REQUIRES_NEW.

MethodA () will be suspended, and a new transaction will be started for serviceb.methodb (). It continues to execute.

The transaction differs from PROPAGATION_REQUIRED in the rollback level of the transaction. Because serviceb.methodb () is a new transaction, there are two different transactions. If servicea.methodb () is committed, then Servicea.methoda () fails to roll back, serviceb.methodb () does not roll back. If serviceb.methodb () fails to roll back, the Servicea.methoda () transaction may still commit if the exception it throws is caught by Servicea.methoda ().

PROPAGATION_SUPPORTS

If serviceb.methodb () has a transaction level PROPAGATION_SUPPORTS, execute serviceb.methodb () and if servicea.methoda () already has a transaction enabled, add the current transaction, If servicea.methoda () does not start the transaction, it does not start the transaction itself. In this case, the transactionality of the inner method is entirely dependent on the outermost transaction.

PROPAGATION_NESTED

If serviceb.methodb () ‘s transaction attribute is PROPAGATION_NESTED, how do the two coordinate? ServiceB#methodB if rollback, then the internal transaction (i.e., ServiceB#methodB) will be rolled back to the SavePoint before it was executed while the external transaction (i.e., ServiceA#methodA) can be handled in the following two ways:

A. Catch exceptions and execute exception branching logic

void methodA(a) { 
        try { 
            ServiceB.methodB(); 
        } catch (SomeException) { 
            // Perform other services, such as servicec.methodc ();}}Copy the code

If ServiceB. MethodB fails, then execute servicec.methodc (). ServiceB. MethodB is rolled back to the SavePoint before it is executed, so no dirty data is generated. This feature can be used in some special services. Neither PROPAGATION_REQUIRED nor PROPAGATION_REQUIRES_NEW can do this.

If the internal transaction (ServiceB#methodB) is rollback, then the ServiceB. MethodB will be rolled back to the SavePoint before it is executed (in any case). The external transaction (that is, ServiceA#methodA) will decide whether it is commit or rollback, depending on the configuration

The other three transaction propagation attributes are basically useless and will not be analyzed here.

Six, summarized

For projects where transactions are needed, I recommend using Spring’s TransactionCallback interface instead of using Spring transaction annotations. If you do use annotations, be sure to understand the propagation mechanism and isolation level of Spring transactions in detail. Otherwise unexpected effects are likely to occur.

Big welfare

Follow the wechat official account of “Glacier Technology” and reply the keyword “Design Mode” in the background to get the PDF document of “23 Design Modes in Simple Java”. Return keyword “Java8” to obtain the Java8 new features tutorial PDF. “Distributed traffic limiting solutions under 100 million levels of traffic” PDF document, the three PDFS are created by the glacial and collated super core tutorial, interview essential!!

Ok, that’s enough for today! Don’t forget to click a like, to see and forward, let more people see, learn together, progress together!!

Write in the last

If you think glacier wrote good, please search and pay attention to “glacier Technology” wechat public number, learn with glacier high concurrency, distributed, micro services, big data, Internet and cloud native technology, “glacier technology” wechat public number updated a large number of technical topics, each technical article is full of dry goods! Many readers have read the articles on the wechat public account of “Glacier Technology” and succeeded in job-hopping to big factories. There are also many readers to achieve a technological leap, become the company’s technical backbone! If you also want to like them to improve their ability to achieve a leap in technical ability, into the big factory, promotion and salary, then pay attention to the “Glacier Technology” wechat public account, update the super core technology every day dry goods, so that you no longer confused about how to improve technical ability!