A deep understanding of Spring transaction principles and a deep understanding of spring

Source: Internet
Author: User
Tags savepoint

A deep understanding of Spring transaction principles and a deep understanding of spring


I. Basic principles of transactions
The essence of Spring transactions is the database's support for transactions. Without the database's support for transactions, spring cannot provide transaction functions. To use transactions to operate databases only using JDBC, follow these steps:
Get Connection con = DriverManager. getConnection ()
Enable transaction con. setAutoCommit (true/false );
Execute CRUD
Commit transaction/rollback transaction con. commit ()/con. rollback ();
Close connection conn. close ();
With the Spring transaction management function, we can not write the code in steps 2 and 4, but automatically complete it by Spirng. So how does Spring start and close transactions before and after CRUD we write? To solve this problem, we can understand the implementation principle of Spring transaction management as a whole. The following is an example of the annotation method.
The annotation driver is enabled in the configuration file and identified by @ Transactional in related classes and methods.
Spring will parse and generate related beans at startup. At this time, it will view classes and methods with relevant annotations and generate proxies for these classes and methods, and inject the configuration according to the related parameters of @ Transaction. In this way, the related transactions are processed in the proxy (the normal Transaction commit is enabled and the Transaction is rolled back abnormally ).
Transaction commit and rollback at the database layer are implemented through binlog Or redo log.
Ii. propagation attributes of Spring transactions
The propagation attribute of spring transactions defines how spring handles these transactions when multiple transactions exist at the same time. These attributes are defined in TransactionDefinition. The specific constants are described in the following table:
Constant name constant explanation
PROPAGATION_REQUIRED supports the current transaction. If no transaction exists, a new transaction is created. This is the most common choice and the propagation of Spring default transactions.
PROPAGATION_REQUIRES_NEW creates a transaction. If a transaction exists, it is suspended. The new transaction will have nothing to do with the pending transaction. It is two independent transactions. After the outer transaction fails to be rolled back, it cannot roll back the results of the execution of the internal transaction, an exception is thrown when an internal transaction fails. The outer transaction is captured or cannot be rolled back.
PROPAGATION_SUPPORTS supports the current transaction. If no transaction exists, it is executed in non-transaction mode.
PROPAGATION_MANDATORY supports the current transaction. If no transaction exists, an exception is thrown.
PROPAGATION_NOT_SUPPORTED performs operations in non-transactional mode. If a transaction exists, the current transaction is suspended.
PROPAGATION_NEVER is executed in non-transaction mode. If a transaction exists, an exception is thrown.
PROPAGATION_NESTED
If an active transaction exists, it runs in a nested transaction. If no active transaction exists, it is executed according to the REQUIRED attribute. It uses a separate transaction, which has multiple storage points that can be rolled back. Rollback of internal transactions does not affect external transactions. It is valid only for the DataSourceTransactionManager Transaction Manager.
Iii. Database isolation level
Problems caused by isolation-level values
Read-Uncommitted 0 Causes dirty Read
Read-Committed 1 avoids dirty reads and allows non-repeated and Phantom reads.
Repeatable-Read 2 avoids dirty reads and cannot be Read repeatedly. Phantom reads are allowed.
Serializable 3 serializes read, and transactions can only be executed one by one, avoiding dirty reads, non-repeated reads, and Phantom reads. Execution efficiency is slow, so use with caution
Dirty read: A transaction adds, deletes, modifies, and does not commit data. Another transaction can read uncommitted data. If the first transaction is rolled back at this time, the second transaction reads dirty data.
Unrepeatable read: Two read operations are performed in a transaction. The data is modified between the first read operation and the second operation, at this time, the data read twice is inconsistent.
Phantom read: the first transaction batch modifies data within a certain range, and the second transaction adds a piece of data in this range. At this time, the first transaction will lose the modification to the new data.
Summary:
The higher the isolation level, the more data integrity and consistency can be guaranteed, but the greater the impact on concurrency performance.
The default isolation level of most databases is Read Commited, such as SqlServer and Oracle.
The default isolation level of a few databases is Repeatable Read, for example, MySQL InnoDB.
Iv. isolation level in Spring
Constant Interpretation
ISOLATION_DEFAULT: This is the default isolation level of PlatfromTransactionManager. It uses the default transaction isolation level of the database. The other four correspond to the JDBC isolation level.
ISOLATION_READ_UNCOMMITTED is the lowest isolation level of the transaction. It allows another transaction to see the uncommitted data of this transaction. This isolation level will generate dirty reads, which cannot be repeated and Phantom reads.
ISOLATION_READ_COMMITTED ensures that the data modified by one transaction can be read by another transaction only after it is committed. Another transaction cannot read the uncommitted data of the transaction.
The transaction isolation level of ISOLATION_REPEATABLE_READ can prevent dirty reads and prevent repeated reads. However, phantom reading may occur.
ISOLATION_SERIALIZABLE this is the most costly but reliable transaction isolation level. Transactions are processed in sequence.
V. Nesting of transactions
Based on the theoretical knowledge above, we have roughly learned some attributes and features of database transactions and spring transactions. Next we will analyze some nested transaction scenarios, to deeply understand the mechanism of spring transaction propagation.
Assume that Method A () of the outer Transaction Service A calls Method B () of the inner Service B ()
PROPAGATION_REQUIRED (spring default)
If ServiceB. the transaction level of methodB () is defined as PROPAGATION_REQUIRED, then ServiceA is executed. when methodA () is used, spring has started a transaction, and ServiceB is called. methodB (), ServiceB. methodB. the internal transactions of methodA () will no longer start new transactions.
If ServiceB. methodB () finds that it is not in the transaction, it will assign a transaction to it.
In this way, the transaction will be rolled back if an exception occurs anywhere in ServiceA. methodA () or ServiceB. methodB.
PROPAGATION_REQUIRES_NEW
For example, the transaction level of ServiceA. methodA () is PROPAGATION_REQUIRED, and that of ServiceB. methodB () is PROPAGATION_REQUIRES_NEW.
Then, when ServiceB is executed. serviceA. the transaction where methodA () is located will be suspended, ServiceB. methodB () starts a new transaction and waits for ServiceB. after the methodB () transaction is completed, it continues to execute.
The difference between the PROPAGATION_REQUIRED transaction and PROPAGATION_REQUIRED is the transaction rollback degree. Because ServiceB. methodB () is a new transaction, there are two different transactions. If ServiceB. methodB () has been submitted, ServiceA. methodA () fails to roll back, And ServiceB. methodB () does not roll back. If ServiceB. methodB () fails to roll back, if the exception thrown by him is ServiceA. methodA () capture, ServiceA. the methodA () transaction may still be committed (mainly depending on whether the exception thrown by B is A rollback exception ).
PROPAGATION_SUPPORTS
Assume ServiceB. the transaction level of methodB () is PROPAGATION_SUPPORTS, when it is executed to ServiceB. if ServiceA. if methodA () has enabled a transaction, it is added to the current transaction. If ServiceA. if methodA () does not start a transaction, it does not start the transaction itself. In this case, the transaction of the internal method is completely dependent on the transaction of the outermost layer.
PROPAGATION_NESTED
The current situation becomes more complex. The transaction attribute of ServiceB. methodB () is configured as PROPAGATION_NESTED. How can the two work together? If ServiceB # methodB is rollback, internal transactions (that is, ServiceB # methodB) will be rolled back to the SavePoint before execution, and external transactions (that is, ServiceA # methodA) can be processed in the following two ways:
A. Capture exceptions and execute the exception branch Logic
Void methodA (){
Try {
ServiceB. methodB ();
} Catch (SomeException ){
// Execute other services, such as ServiceC. methodC ();
}
}
This method is also the most valuable place for nested transactions. It plays a role in branch execution if ServiceB. methodB failed, then ServiceC. methodC (), while ServiceB. methodB has rolled back to its SavePoint before execution, so no dirty data is generated (equivalent to this method has never been executed). This feature can be used in some special services, neither PROPAGATION_REQUIRED nor PROPAGATION_REQUIRES_NEW can achieve this.
B. The external transaction rollback/commit code is not modified. If the internal transaction (ServiceB # methodB) rollback, first ServiceB. methodB rolls back to the SavePoint before it executes (in any case), and the external transaction (that is, ServiceA # methodA) determines whether it is a commit or rollback based on the specific configuration.
The other three transaction propagation attributes are basically unavailable and will not be analyzed here.
Vi. Summary
For transactions that need to be used in the project, I suggest developers still use the TransactionCallback interface of spring to implement transactions. Do not blindly use spring transaction annotations. If annotations are required, therefore, you must have a detailed understanding of the propagation mechanism and isolation level of spring transactions. Otherwise, unexpected results may occur.

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: info-contact@alibabacloud.com 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.