A detailed description of spring declarative transaction management and configuration

Source: Internet
Author: User
Tags savepoint

Reprint: http://www.cnblogs.com/hellojava/archive/2012/11/21/2780694.html

1. Five ways of spring declarative transaction configuration

The previous period of time has done a more in-depth study of the transaction configuration of spring, although the transaction configuration of spring has been configured, but there is no clear understanding. Through this study found that spring's business configuration as long as the idea is clear, or better mastered.

Summarized as follows:

The spring configuration file about transaction configuration is always composed of three components, namely, DataSource, TransactionManager and agent mechanism of the three parts, regardless of which configuration method, the general change is only the agent mechanism this part.

DataSource, TransactionManager These two parts only according to the data access way change, for example uses Hibernate to carry on the data access, DataSource actually is sessionfactory, The implementation of TransactionManager is Hibernatetransactionmanager.

Specific example:

According to the different agent mechanism, the configuration of five kinds of spring transactions is summarized, and the configuration file is as follows:

The first way: Each bean has a proxy

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns:    Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "Http://www.springframework.org/schema/context" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xsi:schemalocation= "Http://www.springframework.org/schema /beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.or G/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd Http://www.sprin GFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/spring-aop-2.5.xsd "> <bean id=" Sessionfactory "class=" Org.springframework.orm.hibernate3.LocalSessionFactoryBean "> <property name=" Configlocation "value=" Classpath:hibernate.cfg.xml "/> <property name=" ConfigurationClass "value=" Org.hiberna Te.cfg.AnnotationConfiguration "/> </bean> <!--define Transaction tubesManager (declarative transaction)--<bean id= "TransactionManager" class= " Org.springframework.orm.hibernate3.HibernateTransactionManager "> <property name=" sessionfactory "ref=" Sessionfactory "/> </bean> <!--configuration Dao--<bean id=" Userdaotarget "class=" Com.bluesky.spring.da O.userdaoimpl "> <property name=" sessionfactory "ref=" sessionfactory "/> </bean> <bean id=" u         Serdao "class=" Org.springframework.transaction.interceptor.TransactionProxyFactoryBean "> <!--Configuration transaction Manager-- <property name= "TransactionManager" ref= "TransactionManager"/> <property name= "target" ref= "UserD Aotarget "/> <property name=" proxyinterfaces "value=" Com.bluesky.spring.dao.GeneratorDao "/> <!- -Configure transaction Properties--<property name= "transactionattributes" > <props> <prop key=  "*" >PROPAGATION_REQUIRED</prop> </props> </property>  </bean></beans> 

the second way: all beans share a proxy base class

... <bean id= "sessionfactory" class= "Org.springframework.orm.hibernate3.LocalSessionFactoryBean" > <p Roperty name= "configlocation" value= "Classpath:hibernate.cfg.xml"/> <property name= "ConfigurationClass" Valu E= "Org.hibernate.cfg.AnnotationConfiguration"/> </bean> <!--define transaction manager (declarative transaction)--<bean id= "tra Nsactionmanager "class=" Org.springframework.orm.hibernate3.HibernateTransactionManager "> <property name=" Sessionfactory "ref=" sessionfactory "/> </bean> <bean id=" transactionbase "class=" org.springframework.tr        Ansaction.interceptor.TransactionProxyFactoryBean "lazy-init=" true "abstract=" true "> <!--Configuration transaction Manager-- <property name= "TransactionManager" ref= "TransactionManager"/> <!--Configuring transaction Properties--<property Name= "Transactionattributes" > <props> <prop key= "*" >propagation_required</prop > &LT;/PROPS&GT </property> </bean> <!--Configuring DAO--<bean id= "Userdaotarget" class= "Com.bluesky.spring.dao.Us Erdaoimpl "> <property name=" sessionfactory "ref=" sessionfactory "/> </bean> <bean id=" UserD AO "parent=" transactionbase "> <property name=" target "ref=" Userdaotarget "/> </bean>

the third way: using interceptors

... <bean id= "sessionfactory" class= "Org.springframework.orm.hibernate3.LocalSessionFactoryBean" > <p Roperty name= "configlocation" value= "Classpath:hibernate.cfg.xml"/> <property name= "ConfigurationClass" Valu E= "Org.hibernate.cfg.AnnotationConfiguration"/> </bean> <!--define transaction manager (declarative transaction)--<bean id= "tra Nsactionmanager "class=" Org.springframework.orm.hibernate3.HibernateTransactionManager "> <property name=" Sessionfactory "ref=" sessionfactory "/> </bean> <bean id=" Transactioninterceptor "class=" Org.springframe Work.transaction.interceptor.TransactionInterceptor "> <property name=" TransactionManager "ref=" TransactionManager "/> <!--Configuring transaction Properties--<property name=" Transactionattributes "> &lt ;p rops> <prop key= "*" >PROPAGATION_REQUIRED</prop> </props> </prop erty> </bean> <bean Class= "Org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" > <property name= "Beannames" >        <list> <value>*Dao</value> </list> </property> <property name= "Interceptornames" > <list> <value>transactioninterceptor</ value> </list> </property> </bean> <!--Configuring DAO--<bean id= "UserD    AO "class=" Com.bluesky.spring.dao.UserDaoImpl "> <property name=" sessionfactory "ref=" Sessionfactory "/> </bean>

Fourth way: Interceptors configured with the TX tag

<?xml version= "1.0" encoding= "UTF-8"?>
<beans xmlns= "Http://www.springframework.org/schema/beans"
xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"
xmlns:context= "Http://www.springframework.org/schema/context"
xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP"
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.5.xsd
Http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/TX/HTTP/ Www.springframework.org/schema/tx/spring-tx-2.5.xsd "> <context:annotation-config/> <context: Component-scan base-package= "Com.bluesky"/> <bean id= "sessionfactory" class= " Org.springframework.orm.hibernate3.LocalSessionFactoryBean "> <property name=" configlocation "value=" Classpath:hibernate.cfg.xml "/> <property name=" ConfigurationClass "value=" Org.hibernate.cfg.AnnotationConfi Guration "/> </bean> <!--define transaction manager (declarative transaction)--<bean id=" TransactionManager "class=" ORG.SPRINGFR Amework.orm.hibernate3.HibernateTransactionManager "> <property name=" sessionfactory "ref=" Sessionfactory "/& Gt </bean> <tx:advice id= "Txadvice" transaction-manager= "TransactionManager" > <tx:attributes> <tx:method name= "*" propagation= "REQUIRED"/> &LT;/TX:ATTRIBUTES&GT </tx:advice> <aop:config> <aop:pointcut id= "interceptorpointcuts" expression= "Execution (* Com.blu Esky.spring.dao.*.* (..)) " /> <aop:advisor advice-ref= "Txadvice" pointcut-ref= "interceptorpointcuts"/> </aop:config>
</bean>

Fifth way: Full annotation

......    <context:annotation-config/>    <context:component-scan base-package= "Com.bluesky"/> <tx    : Annotation-driven transaction-manager= "TransactionManager"/>    <bean id= "sessionfactory" class= " Org.springframework.orm.hibernate3.LocalSessionFactoryBean ">        <property name=" configlocation "value=" Classpath:hibernate.cfg.xml "/>        <property name=" ConfigurationClass "value=" Org.hibernate.cfg.AnnotationConfiguration "/>    </bean>    <!--define transaction manager (declarative transaction)--    < Bean id= "TransactionManager" class= "Org.springframework.orm.hibernate3.HibernateTransactionManager" >        <property name= "Sessionfactory" ref= "sessionfactory"/>    </bean>

At this point, you need to add @transactional annotations on DAO, as follows:

@Transactional @component ("Userdao") public class Userdaoimpl extends Hibernatedaosupport implements Userdao {    Public list<user> listUsers () {        return this.getsession (). CreateQuery ("from User"). List ();    }    ......}

Note: The above section is reproduced from http://www.blogjava.net/robbie.html

2. propagation properties of a transaction (propagation)

The Propagation:key property determines which method the agent should add the transaction behavior to. The most important part of such a property is the propagation behavior. The following options are available: propagation_required--supports the current transaction and creates a new transaction if no transaction is currently in use. This is the most common choice.

propagation_required--supports the current transaction, and creates a new transaction if there is no current transaction. This is the most common choice. The
propagation_supports--supports the current transaction and is executed in a non-transactional manner if no transaction is currently in use.
propagation_mandatory--supports the current transaction and throws an exception if there is no current transaction.
propagation_requires_new--a new transaction, suspending the current transaction if a transaction is currently present.
propagation_not_supported--performs the operation in a non-transactional manner, suspending the current transaction if a transaction is currently present. The


1:propagation_required
Joining a transaction that is currently being executed is not in another transaction, then a new transaction is started.

For example, Serviceb.methodb's transaction level is defined as propagation_required, Then since the execution of the Servicea.methoda, Servicea.methoda has already started the transaction, when the call Serviceb.methodb,serviceb.methodb see that they have run within the Servicea.methoda of the transaction, no longer A new transaction. And if Servicea.methoda is running and finds himself not in a transaction, he assigns himself a transaction. In this way, the transaction will be rolled back if an exception occurs in the Servicea.methoda or anywhere within the SERVICEB.METHODB. Even if the SERVICEB.METHODB transaction has been committed, but Servicea.methoda will be rolled back in the next fail, Serviceb.methodb will roll back

2:propagation_supports
If you are currently running in a transaction, that is, as a transaction, if you are not currently in a transaction, run as a non-transactional

3:propagation_mandatory
must run in a transaction. In other words, he can only be called by a parent transaction. Otherwise, he's going to throw an exception.

4:propagation_requires_new
that's a bit of a detour. For example, we design Servicea.methoda with a transaction level of Propagation_required,serviceb.methodb of Propagation_requires_new, Then when the execution to the SERVICEB.METHODB, Servicea.methoda the transaction will be suspended, Serviceb.methodb will start a new transaction, waiting for the completion of the SERVICEB.METHODB transaction, he continues to execute. The difference between his affairs and Propagation_required is the degree of rollback of the transaction. Because Serviceb.methodb is a new transaction, there are two different transactions. If the SERVICEB.METHODB has been committed, then Servicea.methoda fails to rollback, SERVICEB.METHODB is not rolled back. If Serviceb.methodb fails to roll back, if the exception he throws is captured by Servicea.methoda, the Servicea.methoda transaction may still be committed.

5:propagation_not_supported
transactions are not currently supported. For example, Servicea.methoda's transaction level is propagation_required, and Serviceb.methodb's transaction level is propagation_not_supported, Then when execution to Serviceb.methodb, Servicea.methoda's transaction hangs, and he runs out of non-transactional state, and then continues the Servicea.methoda transaction.

6:propagation_never
cannot run in a transaction. Suppose the transaction level of Servicea.methoda is propagation_required, and Serviceb.methodb's transaction level is Propagation_never, Then Serviceb.methodb will throw an exception.

7:propagation_nested
the key to understanding nested is savepoint. The difference between him and propagation_requires_new is that propagation_requires_new another transaction, which will be independent of his father's affairs, and that nested's affairs and his father's affairs are interdependent, His submission was to be submitted as a piece of his father's business. In other words, if the parent transaction is finally rolled back, he will also be rolled back.

The advantage of nested affairs is that he has a savepoint.

ServiceA {    //transaction property configured to propagation_required    void MethodA () {        try {            //savepoint            serviceb.methodb () ; propagation_nested level        } catch (someexception) {            //execute other business, such as SERVICEC.METHODC ();}        }}    

That is, SERVICEB.METHODB failure rollback, then Servicea.methoda will also roll back to SavePoint point, Servicea.methoda can choose another branch, such as SERVICEC.METHODC, continue to execute, to try to complete their own transactions 。 However, this transaction is not defined in the EJB standard.

3. Spring Transaction ISOLATION Level (isolation levels)

From low to high by isolation level:

1. Isolation_default: This is a platfromtransactionmanager default isolation level, using the default transaction isolation level of the database.
The other four correspond to the isolation level of JDBC
2. Isolation_read_uncommitted: This is the lowest isolation level of a transaction, which allows a foreign transaction to see the uncommitted data for this transaction.
This isolation level produces dirty reads, non-repeatable reads, and Phantom reads.
3. isolation_read_committed: Ensure that one transaction cannot read to another data that has been modified but not committed by a parallel transaction. Data is submitted before it can be read.


4. isolation_repeatable_read: it is in addition to guaranteeing that one transaction cannot read the uncommitted data of another transaction. It also ensures that the following conditions are avoided (non-repeatable reading). The
      avoid dirty reads and cannot be read repeatedly. However, Phantom reads may occur. But it also leads to more performance damage.
5. isolation_serializable  transactions are processed for sequential execution. The
     , in addition to preventing dirty reads, is not repeatable read, but also avoids phantom reads. This is the most cost-effective, but most reliable, transaction isolation level.

what is dirty data, dirty read, non-repeatable read, hallucination read?

Dirty read: Refers to when a transaction is accessing the data, and the data is modified, and this modification has not yet been committed to the database, then another transaction also accesses the data, and then used this data. Because this data is data that has not yet been submitted, the data that is read by another transaction is dirty, and the operation based on dirty data may not be correct.

Non-repeatable read: Refers to reading the same data multiple times within a transaction. When this transaction is not finished, another transaction accesses the same data. Then, between the two read data in the first transaction, the data that the first transaction two reads may be different because of the modification of the second transaction. This occurs when the data that is read two times within a transaction is not the same and is therefore called non-repeatable read.

Illusion reading: A phenomenon that occurs when a transaction is not executed independently, such as when the first transaction modifies data in a table, which involves all rows of data in the table. At the same time, the second transaction modifies the data in the table by inserting a new row of data into the table. Then the user who will be working on the first transaction in the future finds that there are no modified rows of data in the table, as if the illusion had occurred.

Non-repeatable reading differs from illusion reading: Illusory reading is somewhat similar to non-repeatable reading, but the data that cannot be read repeatedly is inconsistent because the data set he is trying to fetch is changed. But the inconsistency of the data to be read by Phantom reads is not the change in the data set he is reading, but the change in his conditional data set. For example, select Account.id where account.name= "ppgogo*", the first time to read 6 eligible IDs, the second time, because transaction B to the name of an account from "DD" to Change to "Ppgogo1", As a result, 7 data were taken out.

4, a complete example of a common configuration convenient transaction configuration

    <!--configuration DataSource--<bean id= "DataSource" class= "Com.mchange.v2.c3p0.ComboPooledDataSource" Destroy-me thod= "Close" > <property name= "driverclass" value= "${driverclass}" ></property> <property Name= "Jdbcurl" value= "${jdbcurl}" ></property> <property name= "user" value= "${user}" &GT;&LT;/PROPERTY&G        T  <property name= "Password" value= "${password}" ></property> </bean> <!--configuration TransactionManager --<bean id= "TransactionManager" class= "Org.springframework.orm.hibernate3.HibernateTransactionManager"    > <property name= "sessionfactory" ref= "Sessionfactory"/> </bean> <!--define transaction rules--  <tx:advice id= "Txadvice" transaction-manager= "TransactionManager" > <tx:attributes> <!-- Transaction propagation properties, isolation level, optimization for read-only transactions, transaction timeout--<tx:method name= "*" propagation= "REQUIRED" isolation= "DEFAULT" read-only= " True "timeout="-1 "/>        </tx:attributes> </tx:advice> <aop:config> <!--defining facets--<aop:p Ointcut id= "Pointcutid" expression= "Execution (* com.google.code). *.*service.* (..)) " /> <!--defining weaving point rules--<aop:advisor advice-ref= "Txadvice" pointcut-ref= "Pointcutid"/> </ao P:config>

A detailed description of spring declarative transaction management and configuration

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.