Spring's transaction management
Personal blog: www.xiaobeigua.icu
5.1 Spring's transaction management
Transaction was originally a concept in the database, in the Dao layer. But under normal circumstances, you need to promote the transaction to the business layer, that is, the Service layer. This is to be able to use the characteristics of the transaction to manage specific business.
In Spring, transaction management can usually be achieved in the following two ways:
- Use Spring's transaction annotations to manage transactions
- Use AspectJ's AOP configuration management transaction
5.2 Spring transaction management API
Spring's transaction management mainly uses two transaction-related interfaces.
(1) Transaction manager interface (emphasis)
The transaction manager is the PlatformTransactionManager interface object. It is mainly used to complete transaction commit, rollback, and obtain transaction status information.
A. Two commonly used implementation classes
There are two commonly used implementation classes for the PlatformTransactionManager interface:
DataSourceTransactionManager : Used when using JDBC or MyBatis for database operations.
HibernateTransactionManager : Used when using Hibernate for persistent data.
B. Spring's rollback method (understanding)
The default rollback method of Spring transactions is: rollback when runtime exceptions and errors occur , and submit when checked ( compiled ) exceptions occur . However, for the checked exception, the programmer can also manually set its rollback mode.
C. Review errors and exceptions (understand)
The Throwable class is the superclass of all errors or exceptions in the Java language. Only when the object is an instance of this class (or one of its subclasses) can it be thrown through the Java virtual machine or Java's throw statement.
Error is an error that cannot be handled during the running of the program, such as OutOfMemoryError, ThreadDeath, NoSuchMethodError, etc. When these errors occur, the program cannot handle (catch or throw), and the JVM generally terminates the thread.
Another type of error that occurs when a program is compiled and run is called an exception, which is a way for the JVM to notify the programmer. In this way, let the programmer know that an error has occurred or may have occurred, and ask the programmer to deal with it.
Exceptions are divided into runtime exceptions and checked exceptions.
Runtime exceptions are the RuntimeException class or its subclasses, that is, exceptions that only appear at runtime. For example, NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException, etc. are all runtime exceptions. These exceptions are thrown by the JVM and are not required to be handled (caught or thrown) at compile time. However, as long as the code is carefully written and the program is robust enough, runtime exceptions can be avoided.
Checked exceptions, also called compile-time exceptions, are exceptions that must be caught or thrown when the code is written. If they are not handled, they cannot be compiled. Such as SQLException, ClassNotFoundException, IOException, etc. are all exceptions under investigation.
Exceptions other than RuntimeException and its subclasses are all exceptions under investigation. Of course, the subclass of user-defined Exception, that is, the user-defined exception is also the exception under investigation. When the programmer defines an exception, as long as the definition is not clearly declared as a subclass of RuntimeException, the defined exception is the checked exception.
(2) Transaction definition interface
The transaction definition interface TransactionDefinition defines three types of constants related to transaction descriptions: transaction isolation level, transaction propagation behavior, transaction default timeout, and operations on them.
A. Defines five transaction isolation level constants (master)
These constants all begin with ISOLATION_. It looks like ISOLATION_XXX.
- DEFAULT : Adopt the DB default transaction isolation level. MySql's default is REPEATABLE_READ; Oracle
The default is READ_COMMITTED.
- READ_UNCOMMITTED: Read has not been submitted. No concurrency issues have been resolved.
- READ_COMMITTED: Read has been submitted. Solve dirty reads, there are non-repeatable reads and phantom reads.
- REPEATABLE_READ: Repeatable reading. Solve dirty reads, non-repeatable reads, and phantom reads
- SERIALIZABLE: Serialization. There is no concurrency problem.
B. Seven transaction propagation behavior constants are defined (mastery)
The so-called transaction propagation behavior refers to the maintenance of transactions during execution when methods in different transactions are called mutually. For example, the method doSome() in transaction A calls the method doOther() in transaction B, and the maintenance of the transaction during the execution of the call is called transaction propagation behavior. The transaction propagation behavior is added to the method.
The transaction propagation behavior constants all start with PROPAGATION_ and are shaped like PROPAGATION_XXX.
PROPAGATION_REQUIRED PROPAGATION_REQUIRES_NEW PROPAGATION_SUPPORTS
PROPAGATION_MANDATORY PROPAGATION_NESTED PROPAGATION_NEVER PROPAGATION_NOT_SUPPORTED
The specified method must be executed within the transaction. If there is a transaction currently, it will be added to the current transaction; if there is no transaction currently, a new transaction will be created. This propagation behavior is the most common choice, and it is also Spring's default transaction propagation behavior.
If the propagation behavior is added to the doOther() method. If the doSome() method is running in a transaction when the doOther() method is called, the execution of the doOther() method is also added to the transaction. If the doSome() method is not executed within the transaction when the doOther() method is called, the doOther() method will create a transaction and execute it in it.
The specified method supports the current transaction, but if there is no current transaction, it can also be executed in a non-transactional manner.
Always create a new transaction. If there is a transaction currently, the current transaction will be suspended until the new transaction is completed.
C. The default transaction timeout period is defined
The constant TIMEOUT_DEFAULT defines the default timeout period at the bottom of the transaction, and the execution time of the sql statement.
Note that there are more conditions for the timeout of the transaction to work, and the calculation of the timeout is more complicated. Therefore, the default value is generally used for this value.
5.3 Setting up a program example environment
Example : purchase goods trans_sale item
In this example, it is necessary to purchase goods, simulate a user placing an order, add sales records to the order table, and reduce inventory from the goods table. Implementation steps:
Step0: Create a database table
Create two database tables sale, goods sale sales table
sale Sales Table
goods table data
Step1: maven depends on pom.xml
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> 插件 <build> <resources> <resource> <directory>src/main/java</directory><!--所在的目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
Step2: Create an entity class
Create entity classes Sale and Goods
Step3: Define the dao interface
Define two dao interfaces SaleDao, GoodsDao
Step4: Define the SQL mapping file corresponding to the dao interface
Step5: Define the exception class Define the exception class NotEnoughException that may be thrown by the service layer
Step6: Define the Service interface Define the Service interface BuyGoodsService
Step7: Define the implementation class of service
Define the implementation class of the service layer interface BuyGoodsServiceImpl
1. Class definition
Step8: Modify the content of the Spring configuration file
Declare Mybatis objects
Declare business layer objects
Step9: Define the test classDefine the test class MyTest. It can now run without a transaction agent.
5.4 Use Spring's transaction annotations to manage transactions (master)
Through the @Transactional annotation method, transactions can be woven into corresponding public methods to achieve transaction management.
All optional attributes of @Transactional are as follows:
- propagation : used to set transaction propagation attributes. The attribute type is Propagation enumeration, and the default value is
- isolation : used to set the isolation level of the transaction. The attribute type is Isolation enumeration, and the default value is
- readOnly : Used to set whether the method is read-only for the operation of the database. This attribute is boolean, and the default value is false.
- timeout : Used to set the timeout period for this operation to connect to the database. The unit is seconds, the type is int, and the default value is
-1, that is, there is no time limit.
- rollbackFor : Specify the exception class that needs to be rolled back. The type is Class, and the default value is an empty array. Of course, if there is only one exception class, the array may not be used.
- rollbackForClassName : Specify the name of the exception class that needs to be rolled back. The type is String, and the default value is an empty array. Of course, if there is only one exception class, the array may not be used.
- noRollbackFor : Specify the exception class that does not need to be rolled back. The type is Class, and the default value is an empty array. Of course, if there is only one exception class, the array may not be used.
- noRollbackForClassName : Specify the name of the exception class that does not need to be rolled back. The type is String, and the default value is an empty array. Of course, if there is only one exception class, the array may not be used.
It should be noted that if @Transactional is used on methods, it can only be used on public methods. For other non-public methods, if the annotation @Transactional is added, although Spring will not report an error, it will not weave the specified transaction into the method. Because Spring will ignore the @Transaction annotation on all non-public methods.
If the @Transaction annotation is on a class, it means that all methods on the class will be woven into transactions during execution.
Transaction steps to implement annotations:
Copy trans_sale project, new project trans_sale_annotation
1. Declare the transaction manager
2. Turn on annotation driver
transaction-manager: the id of the transaction manager bean
3. Add transaction attributes to the public method of the business layer
5.5 Using AspectJ's AOP configuration management transaction (master)
The disadvantage of using XML to configure transaction agents is that each target class needs to configure transaction agents. When there are many target classes, the configuration file will become very bloated.
Using the XML configuration consultant method can automatically generate transaction agents for each class that meets the pointcut expression. Its usage is very simple, just delete the configuration of the transaction agent in the previous code and replace it with the following content.
Step1: Copy the project
Copy the trans_sale project and rename it to trans_sal_aspectj. Modify on this basis.
Step2: maven depends on pom.xml
Dependent coordinates of newly added aspectj
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.5.RELEASE</version> </dependency>
Step3: Add a transaction manager to the container
Step4 : Configure transaction notification
Set relevant properties for transaction notifications. Used to specify how to weave transactions into which methods.
For example, the transaction requirements applied to the buy method are necessary, and the business must be rolled back when an exception occurs in the buy method.
Step5: Configure the enhancer
Specify to whom the configured transaction notification will be woven.
Step6: Modify the test class
What you want to get from the container in the test class is the target object.