Detailed explanation of spring transaction propagation and its implementation principle

This paper mainly studies the spring transaction propagation and its implementation principle. The details are as follows.

brief introduction

Spring is now a de facto standard for java development, which benefits from its convenience, complete functions, easy to use and so on. In the development process, operating DB is a very common operation, and transactions will be involved when DB is involved. In the normal development process of transactions, even if you don't notice it, the normal execution of the program will not have side effects, but if there are exceptions and the transactions are not handled properly, unexpected results may occur. Spring encapsulates various operations in transactions, especially the emergence of declarative transactions, which makes development more comfortable. Spring extends transactions and supports the definition of multiple propagation attributes, which is also the focus of this article.

What is a transaction

Not strictly speaking, a transaction is the abbreviation of multiple operations. Either all of these operations are effective or none of them are effective (equivalent to not having been executed). A general operation process is simplified as follows:

Some problems can be seen from the above code:

Spring provides declarative transactions, so that we don't pay attention to the specific implementation of the bottom layer and shield a variety of different implementation details of the bottom layer. In order to support the fine control of transactions by a variety of complex businesses, spring provides the propagation properties of transactions, and combined with declarative transactions, it has achieved a great service tool.

Example analysis of spring transaction propagation attribute

In the transactiondefinition class, spring provides six propagation properties, which are illustrated by simple examples.

Warm reminder: joining the current transaction mentioned below means that the underlying layer uses the same connection, but the transaction status object can be recreated without affecting it. As mentioned in the article, there is only one transaction at present, which means sharing an underlying connection, regardless of how many transaction status objects are created.

1、PROPAGATION_ required

Note: if a transaction already exists, join the transaction. If there is no transaction, create a transaction. This is the default propagation attribute value.

Look at a small example. The code is as follows:

Both ServiceA and serviceb declare transactions. By default, propagation = propagation_ Required. There is only one shared transaction in the whole service calling process. When any exception occurs, all operations will be rolled back.

2、PROPAGATION_ SUPPORTS

Note: if a transaction already exists, join the transaction. Otherwise, create a so-called empty transaction (no transaction execution can be considered).

Look at a small example. The code is as follows:

There is currently no transaction when ServiceA is executing, so the exception thrown in the service will not cause ServiceA to roll back.

Let's take another small example. The code is as follows:

Since there is no transaction when ServiceA runs, at this time, if the underlying data source defaultautocommit = true, sql1 is effective. If defaultautocommit = false, sql1 is invalid. If the service has a @ transactional tag, ServiceA shares the transaction of the service (no longer depends on defaultautocommit). At this time, ServiceA is rolled back.

3、 PROPAGATION_ MANDATORY

Description: a transaction must exist at present, otherwise an exception will be thrown.

Look at a small example. The code is as follows:

In this case, an exception will be thrown when executing the service. If defaultautocommit = true, serviceb will not be rolled back. If defaultautocommit = false, serviceb execution is invalid.

4、PROPAGATN_ REQUIRES_ NEW

Note: if there is a current transaction, first encapsulate the relevant contents of the current transaction into an entity, then re create a new transaction, and accept this entity as a parameter for transaction recovery. To put it more bluntly, pause the current transaction (if there is no transaction at present, it is not necessary) and create a new transaction. In this case, the two transactions have no dependency, and the new transaction can be rolled back, but the external transaction continues to execute.

Look at a small example. The code is as follows:

When calling the service interface, ServiceA uses requirements_ New, it will create a new transaction. However, because ServiceA throws a runtime exception, ServiceA is rolled back. In the service method, an exception is caught, so serviceb is submitted normally. Note that the try... Catch code in the service is required, otherwise the service will throw an exception, resulting in the rollback of serviceb.

5、Propagation. NOT_ SUPPORTED

Note: if the current transaction exists, suspend the current transaction, and then execute the new method in the environment without transaction. In the environment without spring transaction, the submission of SQL completely depends on the defaultautocommit attribute value.

Look at a small example. The code is as follows:

When calling the service method and executing the 1 / 0 code in the ServiceA method, an exception is thrown. Because ServiceA is in a transaction free environment, whether sql1 takes effect depends on the value of defaultautocommit. When defaultautocommit = true, sql1 takes effect, but because the service throws an exception, serviceb will be rolled back.

6、 PROPAGATION_ NEVER

Note: if there is a transaction, an exception will be thrown; otherwise, the code will be executed in a transaction free environment.

Look at a small example. The code is as follows:

After the above example calls the service, if defaultautocommit = true, the serviceb method and sql1 in ServiceA will take effect.

7、 PROPAGATION_ NESTED

Note: if there is a current transaction, use savepoint technology to save the current transaction state, and then the bottom layer shares a connection. When there is an internal error in nested, it will roll back to the savepoint state. As long as an exception is caught externally, you can continue to commit the external transaction without being disturbed by the embedded business. However, If an exception is thrown by an external transaction, the whole large transaction will be rolled back.

Note: the spring configuration transaction manager should actively specify nestedtransactionallowed = true, as shown below:

Look at a small example. The code is as follows:

Serviceb is an embedded business. Runtime exceptions are thrown internally, so serviceb is rolled back. Because the service catches exceptions, ServiceA can be submitted normally.

Let's take another example. The code is as follows:

Because the service threw an exception, the whole service method will be rolled back. (this is different from deployment_requirements_new. The embedded business in the nested mode will be rolled back by the exception of external transactions.)

Implementation analysis

The previous examples illustrate several propagation attributes provided by spring transactions, which are used to meet a variety of different business requirements, which can be determined according to the business. Next, let's look at what is the most important technical dependency of spring to implement these propagation properties. This section lists promotion_ REQUIRES_ New and propagation Nested gives a brief description respectively.

1、 PROPAGATION_ REQUIRES_ New implementation principle

The following code calls:

The execution schematic diagram is as follows:

a. Create a transaction state object, get a new connection, and reset the autocommit, fetchsize, timeout and other properties of the connection

b. Bind connection to ThreadLocal variable

c. Suspend the current transaction, encapsulate the current transaction status object, connection and other information into a suspendedresources object, which can be used for recovery

d. Create a new transaction state object, retrieve the new connection, reset the autocommit, fetchsize, timeout and other properties of the new connection, save the suspendedresources object for transaction recovery, and bind the new connection to the ThreadLocal variable (overwrite operation)

e. When an exception is caught, roll back the connection in ThreadLocal, recover the connection parameters, close the connection, and recover suspended resources

f. Submit the connection in the ThreadLocal variable (causing the serviceb to be submitted), restore the connection parameters, close the connection, and return the connection to the data source

Therefore, the result of program execution is that ServiceA is rolled back and serviceb is successfully submitted.

2、 PROPAGATION_ Nested implementation principle

The following code calls:

The execution schematic diagram is as follows:

a. Create a transaction state object, get a new connection, and reset the autocommit, fetchsize, timeout and other properties of the connection

b. Bind connection to ThreadLocal variable

c. Mark to use the current transaction state object, obtain the ThreadLocal connection object, and save the savepoint of the current connection for exception recovery. At this time, the savepoint is the state after ServiceA is executed

d. When an exception is caught, use savepoint in C to roll back the transaction, that is, roll back the state to the state after ServiceA is executed. All executions of serviceb method will not take effect

e. Get the connection object in ThreadLocal, commit the transaction, restore the connection properties, and close the connection

other

Based on the underlying data source, spring uses ThreadLocal, savepoint and other technology points to realize a variety of transaction propagation attributes, which is convenient to realize various complex businesses. Only by understanding the principle of propagating attributes can we better control spring transactions. Spring rollback transaction depends on exception capture. By default, the transaction will be rolled back only when runtimeException and error are thrown. Of course, it can be configured. For more information, please see the annotation @ transactional.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>