歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Spring中事務管理淺談

Spring中對事務的聲明式管理

拿一個XML舉例

[html]
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:aop="http://www.springframework.org/schema/aop"  
  5.        xmlns:tx="http://www.springframework.org/schema/tx"  
  6.        xsi:schemaLocation="  
  7.        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
  8.        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd  
  9.        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">  
  10.   
  11.   
  12.   事務管理目標Service  
  13.   <bean id="fooService" class="x.y.service.DefaultFooService"/>  
  14.     
  15.   切面配置,配置了切入點是執行FooService下的所有方法 和 切入點調用的通知器為txAdvice  
  16.   <aop:config>  
  17.     <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>  
  18.     <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>  
  19.   </aop:config>  
  20.     
  21.   該通知器的具體配置,所使用的事務管理器,所配置的事務規則  
  22.   <tx:advice id="txAdvice" transaction-manager="txManager">  
  23.     <!-- the transactional semantics... -->  
  24.       
  25.     <tx:attributes>  
  26.       <!-- all methods starting with 'get' are read-only -->  
  27.         
  28.       <tx:method name="get*" read-only="true"/>  
  29.       <!-- other methods use the default transaction settings (see below) -->  
  30.         
  31.       <tx:method name="*"/>  
  32.     </tx:attributes>  
  33.   </tx:advice>  
  34.   
  35.   所選用的事務管理器,和作為啟動參數塞入的dataSource  
  36.   <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  37.     <property name="dataSource" ref="dataSource"/>  
  38.   </bean>  
  39.   
  40.   
  41.   連接數據庫的dataSource  
  42.   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  43.     <property name="driverClassName" value="Oracle.jdbc.driver.OracleDriver"/>  
  44.     <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>  
  45.     <property name="username" value="scott"/>  
  46.     <property name="password" value="tiger"/>  
  47.   </bean>  
  48.     
  49. </beans>  

Spring中對事務管理的底層實現

以上的方法,選用了Spring本身自帶的JDBC的事務控制器做處理。

相關代碼集中在DataSourceTransactionManager中

比如,事務的取得並且將取得的事務捆綁進當前線程中

[java]
  1. @Override  
  2.     protected Object doGetTransaction() {  
  3.         DataSourceTransactionObject txObject = new DataSourceTransactionObject();  
  4.         txObject.setSavepointAllowed(isNestedTransactionAllowed());  
  5.         ConnectionHolder conHolder =  
  6.             (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);  
  7.         txObject.setConnectionHolder(conHolder, false);  
  8.         return txObject;  
  9.     }  

在比如事務的開始,

[java]
  1. /** 
  2.      * This implementation sets the isolation level but ignores the timeout. 
  3.      */  
  4.     @Override  
  5.     protected void doBegin(Object transaction, TransactionDefinition definition) {  
  6.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;  
  7.         Connection con = null;  
  8.   
  9.         try {  
  10.             if (txObject.getConnectionHolder() == null ||  
  11.                     txObject.getConnectionHolder().isSynchronizedWithTransaction()) {  
  12.                 Connection newCon = this.dataSource.getConnection();  
  13.                 if (logger.isDebugEnabled()) {  
  14.                     logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");  
  15.                 }  
  16.                 txObject.setConnectionHolder(new ConnectionHolder(newCon), true);  
  17.             }  
  18.   
  19.             txObject.getConnectionHolder().setSynchronizedWithTransaction(true);  
  20.             con = txObject.getConnectionHolder().getConnection();  
  21.   
  22.             Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);  
  23.             txObject.setPreviousIsolationLevel(previousIsolationLevel);  
  24.   
  25.             // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,   
  26.             // so we don't want to do it unnecessarily (for example if we've explicitly   
  27.             // configured the connection pool to set it already).   
  28.             if (con.getAutoCommit()) {  
  29.                 txObject.setMustRestoreAutoCommit(true);  
  30.                 if (logger.isDebugEnabled()) {  
  31.                     logger.debug("Switching JDBC Connection [" + con + "] to manual commit");  
  32.                 }  
  33.                 con.setAutoCommit(false);  
  34.             }  
  35.             txObject.getConnectionHolder().setTransactionActive(true);  
  36.   
  37.             int timeout = determineTimeout(definition);  
  38.             if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {  
  39.                 txObject.getConnectionHolder().setTimeoutInSeconds(timeout);  
  40.             }  
  41.   
  42.             // Bind the session holder to the thread.   
  43.             if (txObject.isNewConnectionHolder()) {  
  44.                 TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());  
  45.             }  
  46.         }  
  47.   
  48.         catch (Exception ex) {  
  49.             DataSourceUtils.releaseConnection(con, this.dataSource);  
  50.             throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);  
  51.         }  
  52.     }  

等等這裡就不多說了,起個頭。

Copyright © Linux教程網 All Rights Reserved