Spring Transaction Configuration

Source: Internet
Author: User
Tags naming convention

Transaction configuration
    • First add the following to/web-inf/applicationcontext.xml:
<!--configuration Transaction Manager-
<bean id= "TransactionManager" class= "Org.springframework.orm.hibernate3.HibernateTransactionManager" >
   <property name= "Sessionfactory" >
       <ref bean= "Mysessionfactory"/>
   </property>
</bean>

Note: This is the transaction manager bean that is used as a public. This will be configured beforehand, without the need for each module to be fitted separately.

    • The following is the detailed information about the transaction management that is configured for each module that must be configured in the respective Applicationcontext-xxx-beans.xml section.

The first is to configure the transaction propagation characteristics, as follows:

<!--  Configure transaction propagation characteristics--
<tx:advice id= "Testadvice" transaction-manager= "TransactionManager" >
    <tx:attributes>
      <tx:method name= "save*" propagation= "REQUIRED"/>
      <tx:method name= "del*" propagation= "REQUIRED"/>
      <tx:method name= "update*" propagation= "REQUIRED"/>
      <tx:method name= "add*" propagation= "REQUIRED"/>
      <tx:method name= "find*" propagation= "REQUIRED"/>
      <tx:method name= "get*" propagation= "REQUIRED"/>
      <tx:method name= "apply*" propagation= "REQUIRED"/>
    </tx:attributes>
</tx:advice>
<!--  Configure the class that participates in the transaction--
<aop:config>
<aop:pointcut id= "Alltestservicemethod" expression= "Execution (* com.test.testada.test.model.service.*.* (..))" />
<aop:advisor pointcut-ref= "Alltestservicemethod" advice-ref= "Testadvice"/>
</aop:config>

Places to be aware of:

(1) Advice (recommended) naming: Because each module will have its own advice, so in the name of the need to make a specification, the initial idea is the module name +advice (just a naming specification).

(2) The tx:attribute tag is a named type that is configured as a method of a transaction .

such as <tx:method name= "save*" propagation= "REQUIRED"/>

where * is a wildcard, which represents all methods that begin with save, that is, a method that conforms to this naming convention as a transaction.

propagation= "REQUIRED" represents support for the current transaction, and if no transaction is currently present, a new transaction is created. This is the most common choice.

(3) Aop:pointcut tags Configure the classes that participate in the transaction, because the database business operation is performed in the service, and should be the service class that contains the methods that are used as transactions.

The first thing you should pay special attention to is the name of the ID, also because each module has its own transaction facets, so I think the preliminary naming rules because the all+ module name +servicemethod. And the difference between each module also lies in the following sentence:

expression= "Execution (* com.test.testada.test.model.service.*.* (..))"

The first of these * represents the return value, the second * represents the service child package, the third * represents the method name, "(.. ) "represents a method parameter.

(4) The aop:advisor tag is to integrate the transaction management attributes that we have configured above as the whole transaction management.

Graphic:

Here are some relevant information about configuring declarative transactions, which are derived from the Internet:

Attached one, spring transaction type detailed

Annex II, a little supplement to the description of the spring transaction type (about nested transactions)

The benefits of the transaction suffix to declarative transaction management

The configuration of four declarative transactions in spring

Attached one, spring transaction type detailed

<prop key= "load*" >propagation_required,readonly</prop><prop key= "store*" >PROPAGATION_REQUIRED </prop>

It is estimated that many friends have not clarified the meaning of the value inside, carefully read the following should know what the situation below should use what kind of statement. ^_^

Common transaction types in spring:

propagation_required--supports the current transaction and creates a new transaction if there is no current transaction. This is the most common choice.

propagation_supports--supports the current transaction and is executed in a non-transactional manner if no transaction is currently in use.

The 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.

The propagation_not_supported--executes the operation in a non-transactional manner, suspending the current transaction if a transaction is currently present.

The propagation_never--is executed in a non-transactional manner and throws an exception if a transaction is currently present.

propagation_nested--executes within a nested transaction if a transaction is currently present. If there is currently no transaction, do something similar to propagation_required.

Annex II, a little supplement to the description of the spring transaction type (about nested transactions)

· propagation_required--supports the current transaction and creates a new transaction if there is no current transaction. This is the most common choice.

· propagation_supports--supports the current transaction and is executed in a non-transactional manner if no transaction is currently in use.

· The 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.

· The propagation_not_supported--executes the operation in a non-transactional manner, suspending the current transaction if a transaction is currently present.

· The propagation_never--is executed in a non-transactional manner and throws an exception if a transaction is currently present.


Perhaps everyone to propagation_nested still do not know, think it is necessary to add ^_^!
Propagation_nested: The nested transaction type is relative to the six cases mentioned above (the six above should be called a flat transaction type), for example I now have a transaction mainly have a few parts:
1, minus 100 dollars from a user account
2, add 100 dollars to the B user account
This is different from the previous transaction may be no difference, I now have a special request is that a user has 3 accounts, B users have 2 accounts, now my requirement is as long as a user's 3 account of any one minus 100 yuan, to B users of two accounts in any one of the increase of 100 yuan on it!
Once you have this requirement, the nested transaction type is perfect for you! We can understand that,
One: "Subtract 100 dollars from a user account" and "add 100 yuan to the B user account" We think for the time being a first-level transaction operation
Two: will be from a user's 3 account of any one of the accounts to reduce the money as a "from a user account minus 100 yuan" sub-transaction (secondary transaction), the same as the back of the savings as another two-level transaction.
Question one: When level two transactions are rollback first-level transactions will not be rollback?
The answer is no, the rollback of the second-level business is only for oneself.
Question two: When will this level of business commit and when would it be rollback?
We mainly look at the situation in level two, when all the two-level transactions are commit and the first-level transaction does not have a failed operation, the whole transaction is a successful transaction, in which case the entire transaction will be commit.
When any two-level transaction is not commit the whole transaction is a failure, and the whole transaction is roolback.
Let's take the example above to illustrate it! If I am in a three account of the operation of the reduction of money by the second level of business to rollback, that is, 3 accounts have not lost money to succeed, the whole business will be rollback failure. If a user account has three accounts with one account that can deduct money and a user of B has two accounts in it, there can be an increase in the money, and if the whole business succeeds, it will be a commit.
Look at the above example seems to be not very deep, look at the situation (a user's 3 accounts have a credit limit, that is, can be overrun, but the amount of overspending is limited). But the principle is the same, simple point to explain a bit, I wish you good luck! ^_^

The benefits of the transaction suffix to declarative transaction management

Good object-oriented programs generally use interfaces and implement separate patterns. I have proposed in the article "Comprehensive analysis of best practices in transaction management" that, in the form of *transaction and *dao suffixes, different uses of the method are differentiated.

This allows the user of the interface's implementation and methods to be alerted to their dependency on database connections and transactions.

In fact, using a naming method such as the *transaction suffix is useful for declarative transaction management. For example, in spring transaction management, we typically use the matching of method names to apply declarative transactions.

One, see the following spring configuration:

    
    
    
    
    
    
    
    
    

This is a spring declarative transaction configuration from a real project. We have this transactional configuration applied to each of the implementation classes of the business layer.

We use read-only transactions for all business services service methods. Transactions are used for methods that begin with Add,save,modify,update,delete,remove,load.

But, in fact, although we develop the software an "information management system", it is developed around the database. However, in the service layer, we still have a lot of methods that do not operate the database.

For example, simply based on business logic to calculate, suitable for the calculation of the cache, the implementation of e-mail, file upload and other tasks of the method, in this configuration are indiscriminate application of the transaction.

The proxy object generated by SPRINGAOP proxies our service implementation class, and all methods are intercepted before and after execution to get and close the database connection, set, Commit, and rollback the transaction. Regardless of whether this method uses the database.

If you follow my approach and use the *transaction suffix to identify the methods that need to handle transactions, we can use spring declarative transactions to apply transactions very precisely and efficiently!

Second, see the following spring transaction configuration:

    
       
    
      

We apply a transaction to this class, which begins with uninstall, contains Wcms, and finally ends with a transaction, so that the rule is named.

Third, part of the source code:

(i) 2 methods for applying Spring declarative transactions:

/** *使用SPring的ibatis,主要要配置iBatis的Spring声明式事务。 *@throwsException *<prop key="uninstall*Wcms*Transaction">PROPAGATION_REQUIRED,-Exception</prop> *1,还要删除所有 频道---新闻--工作流表中标记不为1的记录。 */publicvoid uninstallAllWcmsProcessDefinitionsTransaction() throwsException{ /** * * */this.getWcmsSystemChannelProcessdefinitionDao().deleteAll(); this.getWcmsSystemChannelNewsinfoDao().deleteAllProcessingWcmsSystemChannelNewsinfoModule();     } /** *<prop key="uninstall*Wcms*Transaction">PROPAGATION_REQUIRED,-Exception</prop> *@paramname *@throwsException */publicvoid uninstallWcmsSystemChannelProcessdefinitionTransaction(String name) throwsException{ this.getWcmsSystemChannelProcessdefinitionDao().deleteByProcessdefinitionName(name); this.getWcmsSystemChannelNewsinfoDao().deleteAllProcessingWcmsSystemChannelNewsinfoModuleByProcessdefinitionName(name);     } (二)用到的Dao类,用来实际访问数据库的2个DAO对象。 /***SPring管理的ibatis功能*/privateIWcmsSystemChannelProcessdefinitionDao wcmsSystemChannelProcessdefinitionDao;privateIWcmsSystemChannelNewsinfoDao wcmsSystemChannelNewsinfoDao;

The configuration of four declarative transactions in spring

Let's get down to it.

The configuration of the following two beans is to be used below.

<!--define the transaction manager (declarative transactions)--
<bean id= "TransactionManager"
   class= "Org.springframework.orm.hibernate3.HibernateTransactionManager" >
   <property name= "Sessionfactory" >
    <ref local= "Sessionfactory"/>
   </property>
<!--******* business Logic layer (front-facing encapsulation of each DAO layer) is used primarily in << façade mode >>******
<bean id= "Fundservice"
   class= "Com.jack.fund.service.serviceimpl.FundService" >
   <property name= "Operdao" >
    <ref bean= "Operatordao"/>
   </property>
   <property name= "Producedao" >
    <ref bean= "Fundproducedao"/>
   </property>
   <property name= "Customerdao" >
    <ref bean= "Customerdao"/>
   </property>
   <property name= "Accountdao" >
    <ref bean= "Accountdao"/>
   </property>
   <property name= "Fundaccountdao" >
    <ref bean= "Fundaccountdao"/>
   </property>
   <property name= "Fundtransdao" >
    <ref bean= "Fundtransdao"/>
   </property>

There may be many other modules. <bean id= "Fundservice"/> may be just one of the modules.

The first: Configure declarative transactions in the following way. is also our most common method, it applies to your library table less than the case.

<bean id= "Fundservicedaoproxy"
   class= "Org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
   <!--configuration Transaction Manager-
   <property name= "TransactionManager" >
    <ref bean= "TransactionManager"/>
   </property>
   <!--This property specifies whether the target class is a proxy object, and if the target class does not implement any classes, set true to represent itself-
   <property name= "Proxytargetclass" >
    <value>false</value>
   </property>
   <property name= "Proxyinterfaces" >
    <value>com.jack.fund.service.IFundService</value>
   </property>
   <!--target Bean--
   <property name= "Target" >
    <ref bean= "Fundservice"/>
   </property>
   <!--configuring transaction Properties--
   <property name= "Transactionattributes" >
    <props>
     <prop key= "delete*" >PROPAGATION_REQUIRED</prop>
     <prop key= "add*" >PROPAGATION_REQUIRED</prop>
     <prop key= "update*" >PROPAGATION_REQUIRED</prop>
     <prop key= "save*" >PROPAGATION_REQUIRED</prop>
     <prop   key= "find*" >PROPAGATION_REQUIRED,readOnly</prop>
    </props>
   </property>

There may be other xxxservicedaoproxy. You can see that a business agent service is configured for each functional module. If the module is much more big, it seems that the code is a bit more, found that they are just a little bit different. Then we should think of the thought of inheritance. Use the second method.

The second way: Configure declarative transactions as follows. This situation is suitable for use in relatively more modules.

<!--Use the idea of inheritance to simplify configuration, to put abstract= "true"--
<bean id= "Transactionbase"
   Class= "Org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
   Lazy-init= "true" abstract= "true" >
   <!--configuration Transaction Manager-
   <property name= "TransactionManager" >
    <ref bean= "TransactionManager"/>
   </property>
   <!--configuring transaction Properties--
   <property name= "Transactionattributes" >
    <props>
     <prop key= "delete*" >PROPAGATION_REQUIRED</prop>
     <prop key= "add*" >PROPAGATION_REQUIRED</prop>
     <prop key= "update*" >PROPAGATION_REQUIRED</prop>
     <prop key= "save*" >PROPAGATION_REQUIRED</prop>
     <prop key= "find*" >PROPAGATION_REQUIRED,readOnly</prop>
    </props>
   </property>

and the specific module can be simply configured like this. Just specify the parent of it. The parent class generally puts abstract= "true" because it does not need to be initialized when the container is loaded, and then initializes when it is called by its subclass when it is used.

<bean id= "Fundservicedaoproxy" parent= "Transactionbase" >
   <property name= "Target" >
   <ref bean= "Fundservice"/>
   </property>

With this configuration, if there are multiple modules like Fundservice, you can have a lot less duplicated code.

The Third Way: Configure declarative transactions as follows. Mainly using Beannameautoproxycreator to automatically create transaction agents

<bean id= "Transactioninterceptor"
   
   <property name= "TransactionManager" >
    <ref bean= "TransactionManager"/>
   </property>
   <!--configuring transaction Properties--
   <property name= "Transactionattributes" >
    <props>
     <prop key= "delete*" >PROPAGATION_REQUIRED</prop>
     <prop key= "add*" >PROPAGATION_REQUIRED</prop>
     <prop key= "update*" >PROPAGATION_REQUIRED</prop>
     <prop key= "save*" >PROPAGATION_REQUIRED</prop>
     <prop key= "find*" >PROPAGATION_REQUIRED,readOnly</prop>
    </props>
   </property>
<bean
   class= "Org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
   <property name= "Beannames" >
    <list>
     <value>fundService</value>
    </list>
   </property>
   <property name= "Interceptornames" >
    <list>
     <value>transactionInterceptor</value>
    </list>
   </property>

This method mainly utilizes the principle of interceptors.

The first three methods are generally required to specify a specific module bean. If there are too many modules, such as a large web site, there are generally dozens of modules. We have to think of a fourth way of configuring it. The way the transaction agent is created automatically.

The fourth type: Configure declarative transactions as follows.

<bean id= "Transactioninterceptor"
   
   <property name= "TransactionManager" >
    <ref bean= "TransactionManager"/>
   
<!--auto Agent--
<bean id= "Autoproxy"
   class= "Org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" >
   <!--can be a service or DAO layer (preferably for the business layer *service)--
   <property name= "Beannames" >
    <list>
     <value>*Service</value>
    </list>
   </property>
   <property name= "Interceptornames" >
    <list>
        <value>transactionInterceptor</value>
    </list>
   </property>

An automatic proxy also uses a combination of regular expressions and advice.

<bean id= "Transactioninterceptor"
   
   <property name= "TransactionManager" >
    <ref bean= "TransactionManager"/>
   
<bean id= "Autoproxycreator"
   
<bean id= "Regexpmethodpointcutadvisor"
   class= "Org.springframework.aop.support.RegexpMethodPointcutAdvisor" >
   <property name= "Advice" >
   <ref bean= "Transactioninterceptor"/>
   </property>
   <property name= "pattern" >
   <value>.*</value>
   </property>
   

This method can be used to intercept and transact the specific module.

In your actual project, you can choose different methods according to your situation.

Spring Transaction 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.