Overview Transaction management is critical for enterprise applications, and it guarantees data consistency even in the event of an exception. The Spring framework provides a consistent abstraction of transaction management, with the following characteristics:
- Provides a consistent programming model for different transactional APIs, such as JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistence API and JDO (Java Data Objects)
- Support declarative transaction management, especially annotation-based declarative transaction management, simple and easy-to-use
- Provides a simpler programmatic transaction management API than other transactional APIs such as JTA
- Perfect integration with spring data access abstraction
How transactions are managed
Spring supports both programmatic transaction management and declarative transaction management.
Programmatic transaction management uses Transactiontemplate or uses the underlying platformtransactionmanager directly. For programmatic transaction management, Spring recommends the use of transactiontemplate.
Declarative transaction management is built on the AOP. The essence is to intercept the method before and after it, and then create or join a transaction before the target method starts, committing or rolling back the transaction according to execution after the target method is executed. The greatest advantage of declarative transactions is that you do not need to programmatically manage transactions, so that you do not need to doping transaction-managed code in your business logic code, just make relevant transaction rule declarations in the configuration file (or through @transactional annotations). You can apply transaction rules to the business logic.
It is obvious that declarative transaction management is better than programmatic transaction management, which is the non-intrusive development approach advocated by spring. Declarative transaction management makes business code non-polluting, a common Pojo object that can be fully transactional supported with annotations. The only disadvantage of declarative transactions, compared to programmatic transactions, is that the finer granularity of the latter only works at the method level and cannot be scoped to the code block as a programmatic transaction. But even with this requirement, there are many workarounds, such as the ability to separate code blocks that require transaction management into methods, and so on.
There are two common ways of declarative transaction management, one is an XML configuration file based on the TX and AOP namespaces, and the other is based on @transactional annotations. The annotation-based approach is obviously easier to use and more refreshing.
Whether Autocommit (autocommit) is automatically committed when the connection is closed
Auto Commit
By default, the database is in autocommit mode. Each statement is in a separate transaction, and if the execution succeeds, the transaction is implicitly committed if
Execution failure is an implicit rollback of the transaction.
For normal transaction management, a set of related operations is in one transaction, so the automatic commit mode of the database must be turned off. However, we don't have to worry, spring will set the autocommit attribute of the underlying connection to false.
Org/springframework/jdbc/datasource/datasourcetransactionmanager.java
Switch to manual commit if necessary. This is very expensive in some JDBC drivers,//so we don't want to do it unnecessarily (for example if we ve explicitly// Configured the connection pool to set it already). if (Con.getautocommit ()) {Txobject.setmustrestoreautocommit (true); if (logger.isdebugenabled ()) {logger.debug ("switching JDBC Connection [" + con + "] to Manual commit"); } con.setautocommit (false);}
Some data connection pools provide settings to turn off transaction autocommit, and it's a good idea to turn it off when you set up a connection pool. But C3P0 does not offer this feature, it can only be set by spring.
Because the JDBC specification specifies that when a connection object is established, it should be in autocommit mode, which is the default across the DBMS, and if necessary, you must explicitly turn off auto-commit. C3P0 adheres to this specification, allowing the customer code to explicitly set the required commit mode.
Whether automatic commits when the connection is closed
When a connection is closed, what should be done if there are uncommitted transactions? The JDBC specification does not mention that the C3P0 default policy is to roll back any uncommitted transactions. This is the right strategy, but there is no agreement between the JDBC driver provider on this issue.
C3P0 the Autocommitonclose property defaults to False, it is not necessary to not move it. Or you can explicitly set this property to False, which is more explicit.
Annotation-based declarative transaction management configuration
Spring-servlet.xml
<!--transaction support--><!--platformtransactionmnager--><bean id= "Txmanager" class= " Org.springframework.jdbc.datasource.DataSourceTransactionManager "> <property name=" DataSource "ref=" DataSource "/></bean><!--enable transaction annotation support--><tx:annotation-driven transaction-manager= "Txmanager"/>
Also add the TX namespace to the Spring-servlet.xml
... xmlns:tx= "Http://www.springframework.org/schema/tx" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi:schemalocation= "... http://www.springframework.org/schema/tx http://www.springframework.org/ Schema/tx/spring-tx.xsd ...
MyBatis automatically participates in spring transaction management without the need for additional configuration, Transaction management will not work as long as the data source referenced by Org.mybatis.spring.SqlSessionFactoryBean is consistent with the data source referenced by Datasourcetransactionmanager.
In addition, you need to download the dependency package Aopalliance.jar to the Web-inf/lib directory. Otherwise, spring will report an exception when initialized
Java.lang.noclassdeffounderror:org/aopalliance/intercept/methodinterceptor
Spring Transaction Features
Spring all transaction management policy classes inherit from the Org.springframework.transaction.PlatformTransactionManager interface
Public interface Platformtransactionmanager {transactionstatus gettransaction (transactiondefinition definition) thro WS TransactionException; void commit (Transactionstatus status) throws TransactionException; void rollback (Transactionstatus status) throws TransactionException;}
Where the Transactiondefinition interface defines the following features:
Transaction ISOLATION LEVEL
Isolation level refers to the degree of isolation between several concurrent transactions. Five constants representing the isolation level are defined in the Transactiondefinition interface:
- Transactiondefinition.isolation_default: This is the default value that represents the default isolation level for using the underlying database. For most databases, this value is usually transactiondefinition.isolation_read_committed.
- Transactiondefinition.isolation_read_uncommitted: This isolation level indicates that one transaction can read data that has been modified by another transaction but has not yet been committed. This level does not prevent dirty reads, non-repeatable reads, and Phantom reads, so the isolation level is rarely used. For example, PostgreSQL does not actually have this level.
- Transactiondefinition.isolation_read_committed: This isolation level indicates that a transaction can only read data that has been committed by another transaction. This level prevents dirty reads, which is the recommended value in most cases.
- Transactiondefinition.isolation_repeatable_read: This isolation level indicates that a transaction can repeatedly execute a query multiple times throughout the process, and that the records returned are the same each time. This level protects against dirty reads and non-repeatable reads.
- Transactiondefinition.isolation_serializable: All transactions are executed one after the other, so that there is absolutely no possibility of interference between transactions, that is, the level prevents dirty reads, non-repeatable reads, and Phantom reads. However, this will severely affect the performance of the program. This level is not normally used.
Transactional propagation behavior
The so-called transaction propagation behavior is that if a transaction context already exists before the current transaction is started, there are several options to specify the execution behavior of a transactional method. The transactiondefinition definition includes the following constants that represent propagation behavior:
- Transactiondefinition.propagation_required: If a transaction is currently present, the transaction is joined and a new transaction is created if there is no current transaction. This is the default value.
- Transactiondefinition.propagation_requires_new: Creates a new transaction and suspends the current transaction if a transaction is currently present.
- Transactiondefinition.propagation_supports: If a transaction is currently present, the transaction is joined, and if no transaction is currently present, it will continue in a non-transactional manner.
- Transactiondefinition.propagation_not_supported: Runs in a non-transactional manner, suspending the current transaction if a transaction is currently present.
- Transactiondefinition.propagation_never: Runs in a non-transactional manner and throws an exception if a transaction is currently present.
- Transactiondefinition.propagation_mandatory: If a transaction is currently present, the transaction is joined and an exception is thrown if there is no current transaction.
- Transactiondefinition.propagation_nested: If a transaction is currently present, create a transaction to run as a nested transaction for the current transaction, or if there is no current transaction, The value is equivalent to transactiondefinition.propagation_required.
Transaction timeout
The so-called transaction timeout is the maximum time a transaction is allowed to execute, and if the time limit is exceeded but the transaction is not completed, the transactions are automatically rolled back. The value of int in transactiondefinition represents the time-out, in seconds.
The default setting is the timeout value for the underlying transaction system, or none if the underlying database transaction system does not have a timeout value set.
Transactional read-only properties
Read-only transactions are used in situations where the client code is read-only but does not modify the data, and read-only transactions are used for optimizations under specific scenarios, such as when using Hibernate.
The default is read-write transactions.
Spring Transaction rollback rules
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 determines whether the transaction that throws the exception is rolled back according to the rule.
By default, spring rolls back the transaction only if the exception is thrown as a run-time unchecked exception, which is the subclass of RuntimeException that throws the exception (errors also causes the transaction to be rolled back), while throwing a checked exception does not cause the transaction to be rolled back.
Can be explicitly configured to roll back transactions when those exceptions are thrown, including checked exceptions. You can also explicitly define those exceptions that are thrown without rolling back the transaction.
You can also programmatically use the Setrollbackonly () method to indicate that a transaction must be rolled back, and that the only action you can perform after the call to Setrollbackonly () is to rollback.
@Transactional annotations
@Transactional Properties
Properties |
type |
Description |
Value |
String |
Optional qualifier descriptor, specifying the transaction manager to use |
Propagation |
Enum:propagation |
Optional transaction propagation behavior settings |
Isolation |
Enum:isolation |
Optional Transaction ISOLATION Level setting |
ReadOnly |
Boolean |
Read-write or read-only transactions, default read and write |
Timeout |
Int (in seconds granularity) |
Transaction time-out time setting |
Rollbackfor |
Class object array, must inherit from Throwable |
An array of exception classes that cause transaction rollback |
Rollbackforclassname |
Class An array group, must inherit from Throwable |
An array of exception class names that caused the transaction rollback |
Norollbackfor |
Class object array, must inherit from Throwable |
An array of exception classes that will not cause the transaction to be rolled back |
Norollbackforclassname |
Class An array group, must inherit from Throwable |
An array of exception class names that will not cause the transaction to be rolled back |
Usage
@Transactional can be used on interfaces, interface methods, classes, and class methods. When used on a class, all public methods of the class will have transactional properties of that type, and at the method level we can also use the callout to override the class-level definition.
Although @Transactional annotations can be used on interfaces, interface methods, classes, and class methods, Spring does not recommend using this annotation on an interface or interface method, because it takes effect only when using an interface-based proxy. In addition, @Transactional annotations should only be applied to the public method, which is determined by the nature of Spring AOP. If you use @Transactional annotations on protected, private, or default visibility methods, this is ignored and no exceptions are thrown.
By default, only method calls from outside are captured by the AOP proxy, which means that other methods inside the class that call this class do not cause transactional behavior, even if the called method uses @transactional annotations to decorate.
@Transactional (readOnly = true) public class Defaultfooservice implements Fooservice {public Foo getfoo (String fooname) {//do something}//These settings the annotation properties on the precedence for this method//methods override the same property on the class annotations @Transactional (readonl y = false, propagation = propagation.requires_new) public void Updatefoo (foo foo) {//Do something}}
Spring,mybatis Transaction Management configuration and @transactional annotations use [go]