zoukankan      html  css  js  c++  java
  • 关于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()返回时拦截取得当前线程连接回滚事务,关闭清除连接。

    不知道猜得对不对

  • 相关阅读:
    Tabindex
    bootStrap下拉菜单 点击下拉列表某个元素,列表不隐藏
    ionic--分模块
    ionic--配置路由
    ionic —指令
    一个简单的Makefile的编写【用自己的话,解释清楚这些】
    使用ptrace向已运行进程中注入.so并执行相关函数
    StrictMode模式介绍
    adb server is out of date. killing...
    交叉编译lsof for android
  • 原文地址:https://www.cnblogs.com/sunwei2012/p/1902171.html
Copyright © 2011-2022 走看看