zoukankan      html  css  js  c++  java
  • spring是如何管理 事务的


     Spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活方便。 

      1、传统使用JDBC的事务管理 

      以往使用JDBC进行数据操作,使用DataSource,从数据源中得到Connection,我们知道数据源是线程安全的,而连接不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接。一般的数据源由容器进行管理,包括连接池。例如TOMCAT,WEBSPHERE,WEBLOGIC等这些J2EE商业容器都提供了这个功能。 

      以往的我们使用JDBC在写代码时,事务管理可能会是这样: 

    Connection conn = null; 
    try{ 
     conn = DBConnectionFactory.getConnection; 
     conn.setAutoCommit(false); 
     //do something 
     conn.commit(); //commit transcation 
    }catch(Exception e){ 
     conn.rollback(); 

    finally{ 
     try{ 
      conn.close(); 
     } catch(SQLException se){ //do sth.} 
     //close ResultSet,PreparedStatement,Connection 
     //notice:Maybe ocurr Exception when u close rs,pstmt,conn 


      按照以往的思路来写代码,代码量比较长,而且容易疏忽,忘掉一些try/catch,引发一些异常无法catch,虽然有时候我们会写DBTool类,来关闭这些资源,并且保证在关闭这些资源时,不向外抛异常,但是这样做会导致额外的麻烦。 

      2、Spring提供的编程式的事务处理 

      Spring提供了几个关于事务处理的类:TransactionDefinition //事务属性定义 

      TranscationStatus //代表了当前的事务,可以提交,回滚。 

      PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。 

      我们使用编程式的事务管理流程可能如下: 

      (1) 声明数据源。 

      (2) 声明一个事务管理类,例如:DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager等 

      (3) 在我们的代码中加入事务处理代码: 

    TransactionDefinition td = new TransactionDefinition(); 
    TransactionStatus ts = transactionManager.getTransaction(td); 
    try{ 
     //do sth 
     transactionManager.commit(ts); 
    }catch(Exception e){transactionManager.rollback(ts);} 

      使用Spring提供的事务模板TransactionTemplate: 

    void add() 

     transactionTemplate.execute( new TransactionCallback(){ 
      pulic Object doInTransaction(TransactionStatus ts) 
      { //do sth} 
     } 


      TransactionTemplate也是为我们省去了部分事务提交、回滚代码;定义事务模板时,需注入事务管理对象。 

      3、Spring声明式事务处理 

      Spring声明式事务处理也主要使用了IoC,AOP思想,提供了TransactionInterceptor拦截器和常用的代理类TransactionProxyFactoryBean,可以直接对组件进行事务代理。 

      使用TransactionInterceptor的步骤: 

      (1)定义数据源,事务管理类 

      (2)定义事务拦截器,例如: 

    <bean id = "transactionInterceptor" 
    class="org.springframework.transaction.interceptor.TransactionInterceptor"> 
    <property name="transactionManager"><ref bean="transactionManager"/></property> 
    <property name="transactionAttributeSource"> 
    <value> 
    com.test.UserManager.*r=PROPAGATION_REQUIRED 
    </value> 
    </property> 
    </bean> 

      (3)为组件声明一个代理类:ProxyFactoryBean 

    <bean id="userManager" class="org.springframework.aop.framework.ProxyFactoryBean"> 
    <property name="proxyInterfaces"><value>com.test.UserManager</value></property> 
    <property name="interceptorNames"> 
    <list> 
    <idref local="transactionInterceptor"/> 
    </list> 
    </property> 
    </bean> 

      使用TransactionProxyFactoryBean: 

    <bean id="userManager" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager"><ref bean="transactionManager"/></property> 
    <property name="target"><ref local="userManagerTarget"/></property> 
    <property name="transactionAttributes"> 
    <props> 
    <prop key="insert*">PROPAGATION_REQUIRED</prop> 
    <prop key="update*">PROPAGATION_REQUIRED</prop> 
    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> 
    </props> 
    </property> 
    </bean> 

      TransactionProxyFactoryBean只是为组件的事务代理,如果我们要给组件添加一些业务方面的验证等,可以使用TransactionTemplate加拦截器方式,为组件添加多个拦截器,spring AOP中提供了三类Advice,即前增强,后增强,抛出异常时的增强,可以灵活使用。
  • 相关阅读:
    构建之法(一)
    大二下周总结十四
    寒假学习报告03
    寒假学习报告02
    2019春季学期个人总结
    2019春学习进度报告(第十六周)
    计算英语最长单词连
    2019春学习进度报告(第十五周)
    用户体验评价
    2019春学习进度报告(第十四周)
  • 原文地址:https://www.cnblogs.com/baiduligang/p/4246971.html
Copyright © 2011-2022 走看看