In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)05/31 Report--
In this issue, the editor will bring you the principle analysis of Spring affairs. The article is rich in content and analyzed and described from a professional point of view. I hope you can get something after reading this article.
The basic principles of Spring transactions
The essence of Spring transaction is the transaction support of the database. Without the transaction support of the database, spring can not provide transaction function. For pure JDBC operation databases, if you want to use transactions, follow these steps:
Get connection Connection con = DriverManager.getConnection ()
Open transaction con.setAutoCommit (true/false)
Execute CRUD
Commit transaction / rollback transaction con.commit () / con.rollback ()
Close the connection conn.close ()
After using the transaction management capabilities of Spring, instead of writing the code for steps 2 and 4, we can do it 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 transaction management implementation principle of Spring as a whole.
The following is a brief introduction, with the annotation method as an example
The configuration file opens the annotation driver and identifies the related classes and methods with the annotation @ Transactional.
When spring starts, it parses and generates the relevant bean. At this time, it looks at the classes and methods with relevant annotations, generates proxies for these classes and methods, and injects relevant configuration according to the relevant parameters of @ Transaction. In this way, the relevant transactions are processed for us in the broker (normal commit transaction is enabled, exception rollback transaction is rolled back).
3. The real transaction commit and rollback in the database layer is achieved through binlog or redo log.
Transaction Mechanism of Spring
All data access technologies have transaction mechanisms that provide API to open transactions, commit transactions to complete data operations, or roll back data when errors occur.
The transaction mechanism of Spring uses a unified mechanism to deal with transactions of different data access technologies. Spring's transaction mechanism provides a PlatformTransactionManager interface, and transactions for different data access technologies are implemented using different interfaces, as shown in the table.
Data access Technology and its implementation
The code to define the transaction manager in the program is as follows:
@ Bean public PlatformTransactionManager transactionManager () {JpaTransactionManager transactionManager = new JpaTransactionManager (); transactionManager.setDataSource (dataSource ()); return transactionManager;}
Declarative transaction
Spring supports declarative transactions, and even if annotations are used to select methods that require transactions, it uses @ Transactional annotations to indicate that the method requires transaction support. This is an implementation operation based on AOP.
@ Transactional public void saveSomething (Long id, String name) {/ / Database Operation}
It is important to note here that this @ Transactional annotation comes from the org.springframework.transaction.annotation package, not javax.transaction.
Two implementations of AOP proxy:
Jdk is a proxy interface, and private methods must not exist in the interface, so they will not be intercepted.
Cglib is a subclass, and private's methods still do not appear in the subclass and cannot be intercepted.
Java dynamic proxy.
There are four steps as follows:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
Create your own call handler by implementing the InvocationHandler interface
Create a dynamic proxy class by specifying a ClassLoader object and a set of interface for the Proxy class
The constructor of the dynamic proxy class is obtained through the reflection mechanism, and its only parameter type is the calling processor interface type.
A dynamic proxy class instance is created through the constructor, and the calling handler object is passed as a parameter at construction time.
GCLIB Agent
Cglib (Code Generation Library) is a powerful, high-performance, high-quality Code generation class library. It can extend the Java class and implement the Java interface at runtime.
Cglib encapsulates asm and can dynamically generate new class (subclasses) at run time.
The proxy that cglib uses in AOP,jdk must be interface-based, but cglib does not have this restriction.
The difference in principle:
Java dynamic proxy uses reflection mechanism to generate an anonymous class that implements the proxy interface, and calls InvokeHandler to deal with it before calling the specific method. The cglib dynamic proxy uses asm open source package to load the class file of the proxy object class and generate a subclass by modifying its byte code to deal with it.
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
If the target object implements an interface, JDK's dynamic proxy is used by default to implement AOP
If the target object implements an interface, you can force the use of CGLIB to implement AOP
If the target object does not implement the interface, you must use the CGLIB library, and spring will automatically convert between the JDK dynamic proxy and CGLIB
If the internal method of the class is not a proxy directly, it can be done by maintaining a proxy of its own instance.
@ Service public class PersonServiceImpl implements PersonService {@ Autowired PersonRepository personRepository; / / injects its own proxy object, and the transitivity of the method call transaction within this class will take effect @ Autowired PersonService selfProxyPersonService / * Test transaction transitivity * * @ param person * @ return * / @ Transactional public Person save (Person person) {Person p = personRepository.save (person); try {/ / New transaction rollback selfProxyPersonService.delete () } catch (Exception e) {e.printStackTrace ();} try {/ / use current transaction full rollback selfProxyPersonService.save2 (person);} catch (Exception e) {e.printStackTrace ();} personRepository.save (person); return p } @ Transactional public void save2 (Person person) {personRepository.save (person); throw new RuntimeException ();} @ Transactional (propagation = Propagation.REQUIRES_NEW) public void delete () {personRepository.delete (1L); throw new RuntimeException ();}}
Propagation properties of Spring transactions
The propagation attribute of spring transactions is the behavior that defines how spring should handle multiple transactions when they exist at the same time. These attributes are defined in TransactionDefinition, and the specific constants are explained in the following table:
Database isolation level
Dirty reading: one transaction makes additions and deletions to the data, but is not committed, and another transaction can read the uncommitted data. If the first transaction rolls back at this time, the second transaction reads dirty data.
Unrepeatable read: there are two read operations in one transaction, between the first read operation and the second operation, another transaction modifies the data, and the data read by the two times is inconsistent.
Illusion: the first transaction makes batch modifications to a certain range of data, and the second transaction adds a piece of data to this range, and the first transaction loses the modification to the new data.
Summary:
The higher the isolation level, the better the integrity and consistency of the data, but the greater the impact on concurrency performance.
Most databases default to Read Commited isolation level, such as SqlServer, Oracle
The default isolation level for a few databases is: Repeatable Read, for example: MySQL InnoDB
Isolation level in Spring
Nesting of transactions
Through the foreshadowing of the above theoretical knowledge, we roughly know some properties and characteristics of database transactions and spring transactions, and then we analyze some nested transaction scenarios to deeply understand the mechanism of spring transaction propagation.
Suppose Method A () of outer transaction Service A calls Method B () of inner Service B
PROPAGATION_REQUIRED (spring default)
If the transaction level of ServiceB.methodB () is defined as PROPAGATION_REQUIRED, then spring already has a transaction when ServiceA.methodA () is executed, and ServiceB.methodB () is called, and ServiceB.methodB () sees that it is already running inside the transaction of ServiceA.methodA () and does not start a new transaction.
If ServiceB.methodB () runs and finds that he is not in a transaction, he assigns a transaction to himself.
In this way, if an exception occurs in ServiceA.methodA () or anywhere within ServiceB.methodB (), the transaction will be rolled back.
PROPAGATION_REQUIRES_NEW
For example, we designed ServiceA.methodA () with a transaction level of PROPAGATION_REQUIRED,ServiceB.methodB () and a transaction level of PROPAGATION_REQUIRES_NEW.
Then when ServiceB.methodB () is executed, the transaction of ServiceA.methodA () is suspended, and ServiceB.methodB () starts a new transaction, waiting for the transaction of ServiceB.methodB () to complete before it continues execution.
The transaction difference between him 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 () fails to roll back, and ServiceB.methodB () will not roll back. If ServiceB.methodB () fails to roll back, if the exception he throws is caught by ServiceA.methodA (), the ServiceA.methodA () transaction may still commit (depending on whether the exception thrown by B is an exception that A will roll back).
PROPAGATION_SUPPORTS
Assuming that the transaction level of ServiceB.methodB () is PROPAGATION_SUPPORTS, when executing to ServiceB.methodB (), if you find that ServiceA.methodA () has already opened a transaction, you will join the current transaction, and if you find that ServiceA.methodA () does not open a transaction, you will not open the transaction yourself. In this case, the transactionality of the internal method is completely dependent on the outermost transaction.
PROPAGATION_NESTED
Now that the situation is more complicated, the transaction property of ServiceB.methodB () is configured to PROPAGATION_NESTED, how will the two cooperate? ServiceB#methodB if rollback, then the internal transaction (that is, ServiceB#methodB) will be rolled back to the SavePoint before it is executed, while the external transaction (that is, ServiceA#methodA) can be handled in the following two ways:
Catch exceptions and execute exception branching logic
Void methodA () {try {ServiceB.methodB ();} catch (SomeException) {/ / execute other services, such as ServiceC.methodC ();}}
This method is also the most valuable aspect of nested transactions, it plays the effect of branch execution, if ServiceB.methodB fails, then execute ServiceC.methodC (), and ServiceB.methodB has rolled back to the SavePoint before it was executed, so it will not produce dirty data (equivalent to this method has never been executed), this feature can be used in some special businesses Neither PROPAGATION_REQUIRED nor PROPAGATION_REQUIRES_NEW can do this.
B. The external transaction rollback / commit code does not make any changes, so if the internal transaction (ServiceB#methodB) rollback, then first ServiceB.methodB rolls back to the SavePoint before it is executed (in any case), and the external transaction (that is, ServiceA#methodA) will decide whether it is commit or rollback according to the specific configuration.
The other three transaction propagation attributes are basically useless and will not be analyzed here.
Summary
For where transactions need to be used in the project, I recommend that developers still use spring's TransactionCallback interface to implement transactions, and do not blindly use spring transaction annotations. If you must use annotations, you must have a detailed understanding of the propagation mechanism and isolation level of spring transactions, otherwise unexpected results may occur.
Spring Boot support for transactions
Through the org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration class. We can see that Spring Boot automatically turns on Spring support for annotated transactions
Some concepts of read-only transactions (@ Transactional (readOnly = true))
Concept:
From the point in time set at this point (point in time a) to the end of the transaction, the transaction will not see the data submitted by other firms! Data submitted by others after the point in time a does not appear in the query.
The annotation @ Transcational (readOnly=true) is typically written on the business class, or on its methods, to add transaction control to it. When readOnly=true is added in parentheses, the underlying data source is told that this is a read-only transaction and that for JDBC, read-only transactions are optimized at a certain speed.
If written in this way, other configurations of transaction control will use the default value, the isolation of the transaction is DEFAULT, that is, the isolation level of the underlying data source is REQUIRED, and the propagation of the transaction is REQUIRED, so there will still be transactions. A generation of RuntimeException thrown in the code will still cause the transaction to be rolled back.
Application situation:
If you execute a single query at a time, there is no need to enable transaction support, and the database supports read consistency during SQL execution by default
If you execute multiple query statements at a time, such as statistical query and report query, in this scenario, multiple query SQL must ensure the overall read consistency, otherwise, after the previous SQL query and before the latter SQL query, the data will be changed by other users, then the overall statistical query will appear read data inconsistent. At this time, transaction support should be enabled.
The above is the principle analysis of the Spring transaction shared by the editor. If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.