I. Overview
Transaction management is critical to enterprise applications, and it can ensure data consistency even in exceptional cases. The Spring framework provides a consistent abstraction of transaction management, characterized by a consistent programming model for different transaction APIs, such as JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistence APIs and JDO (Java Data Objects) Support declarative transaction management, especially annotation based declarative transaction management, simple and easy to use
Provides the perfect integration of programmatic transaction management APIs and spring data access abstractions that are simpler than other transaction APIs such as JTA.
1.1. Transaction management Mode
Spring supports both programmatic transaction management and declarative transaction management. Programmatic transaction management uses Transactiontemplate or directly uses the underlying platformtransactionmanager. For programmatic transaction management, Spring recommends using Transactiontemplate. Declarative transaction management is based on AOP. The essence is to intercept the method before and after, and then create or join a transaction before the target method starts, committing or rolling back the transaction based on execution after the target method is executed. The greatest advantage of declarative transactions is that there is no need to programmatically manage transactions so that there is no need to doping the transaction management code in the business logic code, simply by making the relevant transaction rule declarations (or through @transactional annotations) in the configuration file. You can apply a transaction rule to the business logic.
It is obvious that declarative transaction management is superior to programmatic transaction management, which is the non-invasive development approach pioneered by spring. Declarative transaction management enables business code to be free from contamination, and a common Pojo object that can be fully transactional supported by adding annotations. The only deficiency of declarative transactions, compared to programmatic transactions, is that the finer granularity of the latter only works at the method level and does not function as a programmatic transaction to the code block level. But even with this demand, there are a number of workarounds, such as the need to separate the blocks of code needed for transaction management into methods, and so on. Declarative transaction management also has two common approaches, one based on the TX and AOP namespaces, and one based on @transactional annotations. Obviously the annotation based approach is simpler and easier to use and more refreshing
1.2. Spring Transaction rollback Rule
The recommended way to instruct the spring transaction manager to roll back a transaction is to throw an exception within the context of the current transaction. The spring transaction manager catches any unhandled exceptions and then decides whether to roll back the transaction that threw the exception, based on the rule. By default, spring rolls back the transaction only if the exception thrown is a run-time unchecked exception, that is, the thrown exception is a runtimeexception subclass (errors also causes a transaction rollback), and throwing checked exceptions does not cause a transaction rollback. You can explicitly configure the rollback of transactions, including checked exceptions, when those exceptions are thrown. You can also explicitly define those exceptions when they are thrown without rolling back the transaction. You can also programmatically indicate that a transaction must be rolled back by means of a setrollbackonly () method, and the only action you can perform after setrollbackonly () is rolled back.
@Transactional the location of the callout
@Transactional annotations can be annotated on classes and methods, and can be annotated on defined interfaces and interface methods.
If we annotate the @transactional annotation on the interface, it leaves a hidden danger: Because annotations cannot be inherited, the @transactional annotations that are annotated in the business interface are not inherited by the business implementation class. Therefore, there may be cases where the transaction does not start. So, spring suggests that we put @transaction annotations on the implementation class.
The @transactional annotation on the method overrides the @transactional on the class. 1.3, the use of steps
Step one, introduce namespaces in the spring configuration file
Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx= "Http://www.springframework.org/schema/tx"
xsi:schemalocation= "Http://www.springframework.org/schema/beans
Http://www.springframework.org/schema /beans/spring-beans-2.0.xsd Http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/ Spring-tx-2.0.xsd ">
Step two, beans with @transactional annotations are automatically configured for declarative transaction support
<</span>bean id= "Defaulttransactionmanager" class= " Org.springframework.orm.hibernate3.HibernateTransactionManager ">
<</span>property name=" Sessionfactory "ref=" sessionfactory "/>
</</span>bean>
<</span>tx: Annotation-driven transaction-manager= "Defaulttransactionmanager" proxy-target-class= "true"/>
Step three, at the interface or the declaration of the class, write a @transactional.
If only write on the interface, the implementation class of the interface will inherit the concrete method of the implementation class of the interface, and can override the setting at the class declaration.
@Transactional//class-level annotations, methods applicable to all public in the class, propagation behavior of the transaction, and isolation levels
When you use spring's annotated transaction management, you may be a bit overwhelmed with the propagation behavior and isolation level of the transaction, which is described in detail below for easy access.
ways to annotate things: @Transactional
When you mark a class, all the methods in the class are handled by the object.
@Transactional public
class Testservicebean implements Testservice {}
when certain methods in a class do not require things:
@Transactional public
class Testservicebean implements Testservice {
private Testdao dao;
public void Setdao (Testdao dao) {
This.dao = DAO;
}
@Transactional (propagation = propagation.not_supported) public
Listgetall () {return null;}}
Introduction to the behavior of the dissemination of things:
@Transactional (propagation=propagation.required)
If there is a transaction, then join the transaction, if not, create a new one (by default)
@Transactional (propagation=propagation.not_supported)
Container does not open transaction for this method
@Transactional (propagation=propagation.requires_new)
Regardless of whether there is a transaction, create a new transaction, the original suspend, the new execution completed, continue to perform the old transaction
@Transactional (Propagation=propagation.mandatory)
Must be executed in an existing transaction, or throw an exception
@Transactional (Propagation=propagation.never)
Must be executed in a transaction that does not have an exception thrown (as opposed to propagation.mandatory)
@Transactional (Propagation=propagation.supports)
If the other bean calls this method and declares the transaction in the other bean, the transaction is used. If the other bean does not declare a transaction, it is not a transaction.
Things Timeout setting:
@Transactional (timeout=30)//default is 30 seconds
Transaction ISOLATION Level:
@Transactional (isolation= isolation.read_uncommitted)
READ UNCOMMITTED data (dirty reads and non-repeatable reads) basically not used
@Transactional (isolation = isolation.read_committed)
Read committed data (non-repeatable read and Phantom reads occur)
@Transactional (isolation = isolation.repeatable_read)
Repeatable reads (phantom reads occur)
@Transactional (isolation = isolation.serializable)
Serialization
MYSQL: Default to Repeatable_read level
SQL Server: Default to Read_committed
Dirty reads : One transaction reads the uncommitted update data for another transaction
non-repeatable reads : The results returned by reading the same data multiple times in the same transaction are different, in other words,
Subsequent reads can read the updated data that has been committed by another transaction. Instead, repeatable reads are repeated in the same transaction
When reading data, it is guaranteed to be the same as read data, which means that subsequent reads cannot be read to another transaction that has been submitted for update data
Phantom reads : One transaction reads a committed insert data from another transaction
description of common parameters in @Transactional annotations
Parameter name |
Function description |
ReadOnly |
This property is used to set whether the current transaction is read-only, set to true to read-only, false to read-write, and false to the default value. For example: @Transactional (readonly=true) |
Rollbackfor |
This property is used to set an array of exception classes that need to be rolled back, and when the exception in the specified exception array is thrown in the method, the transaction is rolled back. For example: Specify a single exception class: @Transactional (Rollbackfor=runtimeexception.class) Specify multiple exception classes: @Transactional (Rollbackfor={runtimeexception.class,exception.class}) |
continued)
Parameter name |
Function description |
Rollbackforclassname |
This property is used to set an array of exception class names that need to be rolled back, and a transaction rollback occurs when an exception in an array of specified exception names is thrown in the method. For example: Specify a single exception class name: @Transactional (rollbackforclassname= "RuntimeException") Specify multiple Exception class names: @Transactional (rollbackforclassname={"RuntimeException", "Exception"}) |
Norollbackfor |
This property is used to set an array of exception classes that do not need to be rolled back, and when the exception in the specified exception array is thrown in the method, no transaction rollback occurs. For example: Specify a single exception class: @Transactional (Norollbackfor=runtimeexception.class) Specify multiple exception classes: @Transactional (Norollbackfor={runtimeexception.class,exception.class}) |
Norollbackforclassname |
This property is used to set an array of exception class names that do not need to be rolled back, and no transaction rollback occurs when a method throws an exception in an array of specified exception names. For example: Specify a single exception class name: @Transactional (norollbackforclassname= "RuntimeException") Specify multiple exception class names: @Transactional (norollbackforclassname={"RuntimeException", "Exception"}) |
Propagation |
This property is used to set the propagation behavior of a transaction, which can be referenced in table 6-7. For example: @Transactional (propagation=propagation.not_supported,readonly=true) |
Isolation |
This property is used to set the transaction isolation level of the underlying database, the transaction isolation level is used to handle multiple transaction concurrency, typically with the default isolation level of the database, and is not required to be set |
Timeout |
This property is used to set the number of timeout seconds for a transaction, with the default of-1 to never timeout |
iii. Matters of note
1 @Transactional can only be applied to the public method, and for other non-public methods, if you mark @transactional, there is no error, but the method has no transactional functionality.
2 with the Spring transaction manager, Spring is responsible for opening the database, committing, and rolling back. The default encountered runtime exception (throw newruntimeexception ("annotation");) rolled back, that is, rollback when an exception is encountered that is not checked (unchecked) , and the exception that needs to be caught (thrownewexception ("annotation");) does not roll back, that is, when the exception that is checked is encountered (that is, an exception that is not thrown at run time, the compiler will check for exceptions that are checked or checked for exceptions), We're going to have to specify a way to get the transaction rolled back, to add @transactional (Rollbackfor={exception.class, other exceptions}) to all exceptions. If the unchecked exception does not roll back: @Transactional ( Notrollbackfor=runtimeexception.class)
As follows:
@Transactional (Rollbackfor=exception.class)//rollback, rollback when an exception Exception is encountered
public void MethodName () {
throw new Exception ("annotation");
}
@Transactional (Norollbackfor=exception.class)//Specifies no rollback, encounters the runtime exception (Thrownew runtimeexception ("note");) rolls back
Public Itimdaoimpl Getitemdaoimpl () {
throw new RuntimeException ("annotation");
}
3. @Transactional annotations should be applied only to public visibility methods. If you use a @Transactional annotation on a protected, private, or Package-visible method, it will not complain, but the annotated method will not show the configured transaction settings.
4. @Transactional annotations can be applied to interface definitions and interface methods, class definitions, and public methods of classes. However, note that the mere presence of a @transactional annotation is not sufficient to open transactional behavior, it is simply a metadata that can be used by a beans that recognizes @Transactional annotations and the appropriate configuration with transactional behavior. In the example above, it is actually the appearance of the element that opens the transaction behavior.
5. The spring team's recommendation is that you use @Transactional annotations on specific classes (or methods of classes), rather than on any interfaces that the class is to implement. You can, of course, use @Transactional annotations on an interface, but this will only take effect if you set up an interface-based agent. Because annotations are not inherited, this means that if you are using a class based proxy, the transaction settings will not be recognized by the class based proxy, and the object will not be packaged by the transaction agent (which will be recognized as serious). Therefore, accept the suggestions of the spring team and use @transactional annotations on specific classes.