关于spring的事务管理(单数据库):纯属猜测。

事务不应该由dao管理,而应该由service管理

最重要的是如下四个类
DataSource :数据库的Connection连接工厂
DataSourceUtils:
参与同一个事务的多个dao实际上应该是共享同一个conn的。
DataSourceUtils.getConnection(dataSource)取得当前ThreadLocal的conn,如果没有从dataSource创建一个。
DataSourceUtils.releaseConnection(conn, dataSource)未必真正关闭连接。
DataSourceTransactionManager
TransactionProxyFactoryBean;拦截具体业务对象方法调用,中间根据DataSourceTransactionManager设置进行事务管理

文笔不行,说不明白,举个例子:

 dao1{
   method(){
     conn= DataSourceUtils.getConnection(dataSource);
      ...........
     DataSourceUtils.releaseConnection(conn, dataSource);
   } 
 }
 
 dao2{
   method(){
     conn= DataSourceUtils.getConnection(dataSource);
      ...........
     DataSourceUtils.releaseConnection(conn, dataSource);
   } 
 }
 
 service{   method();  }
  
 serviceImp{
   method(){
      dao1.method();
      dao2.method();
   } 
 }
 
 
 <bean id="dataSource"
       class="org.apache.commons.dbcp.BasicDataSource"
       destroy-method="close">
 </bean>      
 <bean id="transactionManager"
       class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     <property name="dataSource">
           <ref local="dataSource" />
     </property>
  </bean>  
  <bean id="service"
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
       <property name="transactionManager">
          <ref bean="transactionManager" />
       </property>
       <property name="target">
          <ref local="serviceImp" />
       </property>
       <property name="transactionAttributes">
          <props>
            <prop key="*">PROPAGATION_REQUIRED</prop>
          </props>
       </property>
  </bean> 

分析:
当调用service.method()时,开始TransactionProxyFactoryBean拦截此方法指定当前线程需要事务,然后调用dao1.method(),
调用conn= DataSourceUtils.getConnection(dataSource)
判断当前线程还没有conn则创建一个,因为此时线程需要事务所以conn.setAutoCommit(false),执行数据库作,
然后DataSourceUtils.releaseConnection(conn, dataSource),判断当前线程需要事务所以不真正关闭连接继续,dao1.method()返回。
调用dao2.method(),调用conn= DataSourceUtils.getConnection(dataSource)判断当前线程有一个conn就返回这个conn,(此时dao1.method()和dao2.method()已经共用了这个conn),执行数据库操作,然后DataSourceUtils.releaseConnection(conn, dataSource),判断当前线程需要事务
所以不真正关闭连接继续,dao2.method()返回。service.method()返回,TransactionProxyFactoryBean拦截取得当前线程连接提交事务,关闭清除连接。这样两个dao就参与到了一个事务当中。如果service.method()抛出异常,则TransactionProxyFactoryBean在service.method()返回时拦截取得当前线程连接回滚事务,关闭清除连接。

不知道猜得对不对

原文地址:https://www.cnblogs.com/sunwei2012/p/1902171.html