How spring Transaction management is implemented: Programmatic transactions and declarative transactions

Source: Internet
Author: User

This article is reproduced in my other blog "http://blog.csdn.net/liaohaojian/article/details/70139151"1. The previous article explained the propagation level and isolation level of spring transactions, as well as the simple configuration of distributed transactions .Click Back to view article2. Programmatic transactions: Encoding for Transaction management (code demo for JDBC Transaction management)

Spring implements programmatic transactions, relying on 2 categories, respectively, the Platformtransactionmanager mentioned in the previous article, and the template class Transactiontemplate (recommended). Here is a detailed description of how spring implements transaction management through this class.

1) Platformtransactionmanager, the previous article has explained the details of the method of the class, do not remember to return to see the article.

transaction manager configuration

<bean id= "DataSource"  class= "Com.mchange.v2.c3p0.ComboPooledDataSource" >     <property name= "Jdbcurl"  value= "${db.jdbcurl}"  />    < Property name= "User"  value= "${user}"  />    <property name= " Password " value=" ${password} " />    <property name=" DriverClass "  value= "${db.driverclass}"  />     <!--the minimum number of connections that are kept in the connection pool.  -->     <property name= "Minpoolsize" >          <value>5</value>     </property>      <!--The maximum number of connections that are kept in the connection pool. Default: 15 -->     <property name= "MaxPoolSize" >          <value>30</value>     </ Property>     < the number of connections obtained!--initialization, and the value should be between Minpoolsize and Maxpoolsize. Default: 3 -->     <property name= "InitialPoolSize" >          <value>10</value>      </property>     <!--Maximum idle time, unused in 60 seconds, the connection is discarded. If 0, it will never be discarded. Default: 0 -->     <property name= "MaxIdleTime" >          <value>60</value>     </ property>     <!--c3p0 The number of connections that are fetched at the same time when the connection in the connection pool is exhausted. Default: 3 -->     <property name= "AcquireIncrement" >          <value>5</value>     < /property>     <!--The standard parameters of JDBC to control the number of preparedstatements loaded within the data source. But due to the statements&nbs of the pre-cachep; belongs to a single connection instead of the entire connection pool. So setting this parameter takes into account a variety of factors.    if both maxstatements and maxstatementsperconnection are 0, the cache is closed. Default: 0 -->     <property name= "MaxStatements" >          <value>0</value>     < /property>     <!--Check for idle connections in all connection pools every 60 seconds. Default: 0 -->     <property name= "IdleConnectionTestPeriod" >          <value>60</value>      </property>     <!--defines the number of repeated attempts to obtain a new connection from the database after a failure. Default: 30 -->     <property name= "AcquireRetryAttempts" >          <value>30</value>      </property>     <!--Getting a connection failure will cause any thread that waits for the connection pool to get the connection to throw an exception. But the numberThe source is still valid   reserved and continues to try to get the connection the next time getconnection () is called. If set to True, the data source will declare broken and permanently shut down after attempting to acquire a connection failure. Default: false -->     <property name= "BreakAfterAcquireFailure" >         <value>true</value>      </property>     <!--Use it only when you need it, due to its high performance consumption. If set to true then the   of each connection submission is officer validated. We recommend using methods such as Idleconnectiontestperiod or automatictesttable to improve the performance of your connectivity tests. Default: false -->     <property name= "TestConnectionOnCheckout" >         <value>false</value>      </property></bean><!-- Datasourcetransactionmanager is located under the Org.springframework.jdbc.datasource package, a data source transaction management class that provides transaction management for a single javax.sql.DataSource data source, primarily for jdbc,m Ybatis Framework transaction Management.  --><bean id= "TransactionManager"  class= "org.springframework.jdbc.datasource.DataSourceTrAnsactionmanager ">    <property name=" DataSource " ref=" DataSource " / ></bean>

import java.util.map;import javax.annotation.resource;import javax.sql.datasource;import  org.apache.log4j.logger;import org.junit.test;import org.junit.runner.runwith;import  org.springframework.jdbc.core.jdbctemplate;import org.springframework.test.context.contextconfiguration; import org.springframework.test.context.junit4.springjunit4classrunner;import  org.springframework.transaction.platformtransactionmanager;import  org.springframework.transaction.transactiondefinition;import  org.springframework.transaction.transactionstatus;import  org.springframework.transaction.support.defaulttransactiondefinition;  @RunWith ( Springjunit4classrunner.class) @ContextConfiguration (locations = {  "Classpath:spring-public.xml"  }) public class test {     @Resource     private  PlatformTransactionManager txManager;     @Resource &NBSP;&NBSP;&Nbsp; private  datasource datasource;    private static  Jdbctemplate jdbctemplate;    logger logger=logger.getlogger (Test.class);     private static final String INSERT_SQL =  "Insert into  testtranstation (SD)  values (?) ";     private static final String COUNT_SQL =  "select  COUNT (*)  from testtranstation ";     @Test     public void  testdelivery () {        //defines the transaction isolation level, propagation behavior,         DefaultTransactionDefinition def = new  Defaulttransactiondefinition ();          def.setisolationlevel ( transactiondefinition.isolation_read_committed);          Def.setpropagationbeHavior (transactiondefinition.propagation_required);          // The transaction state class, which is obtained from the transaction definition through the Gettransaction method of the Platformtransactionmanager; After the transaction state is obtained, spring determines how the transaction is opened based on the propagation behavior          transactionstatus status = txmanager.gettransaction (def);          jdbctemplate = new jdbctemplate (DataSource);         int i = jdbctemplate.queryforint (COUNT_SQL); &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.OUT.PRINTLN ("Total Records in table:" +i);         try {              jdbctemplate.update (insert_sql,  "1");              txmanager.commit (status);   //the transaction that is bound in the status submission          } catch  (RuNtimeexception e)  {              Txmanager.rollback (status);   //rollback         }          i = jdbctemplate.queryforint (Count_sql);     &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;SYSTEM.OUT.PRINTLN ("Total number of records in the table:" +i);     }}

2) using Transactiontemplate, this class inherits the interface Defaulttransactiondefinition, which is used to simplify transaction management, and transaction management is defined by the template class. is specified primarily through the Transactioncallback callback interface or the Transactioncallbackwithoutresult callback interface. Automatically enjoy transaction management by calling the execute method of the template class with the parameter type Transactioncallback or Transactioncallbackwithoutresult.

Transactiontemplate the callback interface used by the template class:

    • Transactioncallback: By implementing the &ldquo; of this interface T dointransaction (transactionstatus status) &rdquo; method to define the operation code that requires transaction management;

    • Transactioncallbackwithoutresult: Inherits Transactioncallback interface, provides &ldquo;void Dointransactionwithoutresult ( Transactionstatus status) &rdquo; convenience interfaces are used to facilitate transaction operation code that does not require a return value.

 @Testpublic  void testtransactiontemplate () {jdbctemplate =  new jdbctemplate (DataSource);    int i =  Jdbctemplate.queryforint (Count_sql);       system.out.println ("Total Records in table:" +i);// Constructor Initialization Transactiontemplatetransactiontemplate template = new transactiontemplate (TxManager ); Template.setisolationlevel (transactiondefinition.isolation_read_committed);   // Overriding the Execute method to implement transaction management Template.execute (New transactioncallbackwithoutresult ()  {@Overrideprotected   Void dointransactionwithoutresult (Transactionstatus status)  {jdbctemplate.update (INSERT_SQL,   "starved to Death");    //field SD is int type, so insert positive failure report exception, auto Rollback, on behalf of Transactiontemplate Automatic Management Transaction}});i =  Jdbctemplate.queryforint (Count_sql);       system.out.println ("Total number of records in table:" +i);} 
3. Declarative transactions: It is obvious that every implementation of a programmatic transaction is implemented separately, but when the business volume is complex, the use of programmatic transactions is undoubtedly painful, and declarative transactions are not intrusive and do not affect the implementation of business logic.

There are 2 types of declarative transaction implementations, one for the implementation of the AOP-related configuration by using spring's <tx:advice> definition transaction notifications, and one for implementing transaction management through @transactional, with detailed instructions on how to configure the 2 methods, Already relevant attention points

1) mode One, the configuration file is as follows

<!-- <tx:advice> defines transaction notifications, which specify transaction properties, where &ldquo;transaction-manager&rdquo; attributes specify the transaction manager, and through &LT;TX: attributes> Specifies the method <tx:method> intercept method that specifically needs to be intercepted, with parameters such as: Name: Method name, inject a matching method into transaction management, wildcard propagation: Transaction propagation behavior, Isolation: Transaction isolation level definition; default = &ldquo;default&rdquo;timeout: Transaction time-out time setting, in seconds, Default-1, indicating transaction timeout will depend on the underlying transaction system ; read-only: Transaction read-only setting, default = False, not read-only,     rollback-for: Exception definition to trigger rollback, can define multiple, to &ldquo;,& rdquo; split, any default runtimeexception will cause the transaction to be rolled back, and any checked exception will not cause the transaction to be rolled back;     No-rollback-for:  exception (s) that are not triggered for rollback, can define multiple, &ldquo;,&rdquo; split;  --><tx:advice id = "Advice"  transaction-manager= "TransactionManager" ><tx:attributes>    <!- -  intercepts the method at the beginning of Save, and the transaction propagation behavior is: REQUIRED: Must have transaction,  if not, create a  --><tx:method name= "save*" in the context  propagation= "REQUIRED"  isolation= "read_committed"  timeout= ""  read-only= "false"   No-rollback-for= " rollback-for=" "/><!--  Support, if there isNo, there is no  --><tx:method name= "*"  propagation= "SUPPORTS"/&GT;&LT;/TX:ATTRIBUTES&GT;&LT;/TX: advice><!--  Define pointcuts, expression is a cut-off point, the following is the specified Impl package of all methods, specific to their own actual requirements of the custom   --><aop:config >    <aop:pointcut expression= "Execution (* com.kaizhi.*.service.impl.*.* (..))"  id= "Pointcut"/>    <!--<aop:advisor> defining pointcuts, with notifications, associating TX with AOP configuration, is the complete declaration transaction configuration  -->    <aop:advisor advice-ref= "Advice"  pointcut-ref= "Pointcut"/> </aop:config>

for transactional propagation behavior and isolation levels, refer to http://blog.csdn.net/liaohaojian/article/details/68488150

Note the point:

    1. Transaction rollback exceptions can only be runtimeexception exceptions, and checked exception exceptions are not rolled back, and catch exceptions are not thrown or rolled back. However, the transaction can be forced to roll back: Transactionaspectsupport.currenttransactionstatus (). Isrollbackonly ();

    2. resolve &ldquo; Self-invoke &rdquo; cannot set the correct transaction property problem, refer to http://www.iteye.com/topic/1122740

2) mode two implement transaction management through @transactional

<bean id= "Txmanager" class= "Org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property Name= "DataSource" ref= "DataSource"/></bean> <tx:annotation-driven transaction-manager= "Txmanager"/ >//Open transaction annotations

@Transactional (propagation=propagation.required,isolation=isolation.read_committed), specific parameters with the above <tx:method> In the same

Spring provides @transaction annotation transaction management, which also internally uses the surround notification transactioninterceptor to enable and disable transactions.
Note Points using @transactional:

    1. If @transactional annotations are specified on an interface, implementation class, or method, the order of precedence is method > implementation Class > interface;

    2. It is recommended that you use @transactional only on methods that implement a class or implementation class, not on an interface, because if you use the JDK proxy mechanism ( an interface-based proxy ) is not a problem, and you encounter problems using the Cglib Proxy (inheritance) mechanism. Because it uses a class-based proxy instead of an interface, this is because the @transactional annotations on the interface are not inherited by &ldquo; &rdquo;;










How spring Transaction management is implemented: Programmatic transactions and declarative transactions

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.