Spring的事务管理机制

55859000 8年前
   <p>本文在<<a href="http://www.open-open.com/lib/view/open1462601828149.html">Spring中使用注解进行事务的配置方式</a>>文章的基础上,一起来学习一下Spring中对事务的支持——Spring的事务管理机制。</p>    <h2>Spring对事务管理的支持</h2>    <p>与EJB类似,Spring提供了对 编码式 和 声明式 事务管理的支持。但是,Spring对事务管理的能力远远超过EJB。这里就不详细介绍编码式事务和声明式事务的区别了。有兴趣的读者可以自行Google。</p>    <p>Spring对事务管理是通过事务管理器来实现的。Spring提供了许多内置事务管理器实现:</p>    <table>     <thead>      <tr>       <th> <p>事务管理器</p> <p>( org.springframework.* )</p> </th>       <th>使用场景</th>      </tr>     </thead>     <tbody>      <tr>       <td>jdbc.datasource.DataSourceTransactionManager</td>       <td>数据源事务管理器,提供对单个 javax.sql.DataSource 事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理;</td>      </tr>      <tr>       <td>orm.jdo.JdoTransactionManager</td>       <td>提供对单个 javax.jdo.PersistenceManagerFactor y事务管理,用于集成JDO框架时的事务管理;</td>      </tr>      <tr>       <td>orm.jpa.JpaTransactionManager</td>       <td>提供对单个 javax.persistence.EntityManagerFactory 事务支持,用于集成JPA实现框架时的事务管理;</td>      </tr>      <tr>       <td>orm.hibernate3.HibernateTransactionManager</td>       <td>提供对单个 org.hibernate.SessionFactory 事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;</td>      </tr>      <tr>       <td>transaction.jta.JtaTransactionManager</td>       <td>提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;</td>      </tr>      <tr>       <td>transaction.jta.OC4JjtaTransactionManager</td>       <td>Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;</td>      </tr>      <tr>       <td>transaction.jta.WebSphereUowTransactionManager</td>       <td>Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;</td>      </tr>      <tr>       <td>transaction.jta.WebLogicJtaTransactionManager</td>       <td>Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。</td>      </tr>     </tbody>    </table>    <p><img src="https://simg.open-open.com/show/7289152906d25e4116dd4e4cb8a32260.png"></p>    <p>以上就是Spring中支持使用的事务管理器,一般我们比较常用的就是 HibernateTransactionManager 和 DataSourceTransactionManager 。我们在使用事务的时候要声明要使用哪种事务管理器。如:</p>    <pre>  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">      <property name="dataSource" ref="dataSource" />  </bean>  </pre>    <h2>事务属性</h2>    <p>spring中,声明事务是通过事务属性来定义的。事务属性描述了事务策略如何应用到方法上事务属性包含5个方面:</p>    <p>传播行为</p>    <p>隔离级别</p>    <p>回滚规则</p>    <p>事务超时</p>    <p>是否只读</p>    <p><img src="https://simg.open-open.com/show/d1acbb450c3fb2ab928500dd4803b7d7.png"></p>    <p>这里简单介绍一下这五个属性。</p>    <h3>传播行为</h3>    <p>传播行为定义了客户端与被调用方法之间的事务边界,即传播规则回答了这样的一个问题,新的事务应该被启动还是挂起,或者方法是否要在事务环境中运行。(后面会有单独的文章介绍该属性)</p>    <h3>隔离级别</h3>    <p>隔离级别定义了一个事务可能受其他并发事务影响的程度。多事务并发可能会导致脏读、幻读、不可重复读等各种读现象。(具体参考:数据库的读现象浅析)</p>    <p>ISOLATION_DEFAULT:使用后端数据库默认的规则</p>    <p>ISOLATION_READ_UNCOMMITTED:允许读取尚未提交的数据变更,可能会导致脏读,幻读或不可重复读</p>    <p>ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以防止脏读,但是幻读或不可重复读仍有可能发生</p>    <p>ISOLATION_REPEATABLE_READ:对同意字段的多次读取结果是一致的,除非数据是被本事务自己所修改,看阻止脏读和不可重复读,但幻读仍有可能发生</p>    <p>ISOLATIOM_SERIALIZABLE:完全服从ACID的隔离级别,确保阻止脏读,不可重复读以及幻读,这是最慢的数据隔离级别</p>    <p>(具体参考: <a href="http://www.open-open.com/lib/view/open1452128134120.html">深入分析事务的隔离级别</a> )</p>    <h3>是否只读</h3>    <p>如果事务只对后端的数据库进行读操作,数据库可以利用事务ID只读特性来进行一些特定的优化。通过将事务设置为只读,你就可以给数据库一个机会,让他应用它认为合适的优化措施。因为是否只读是在事务启动的时候由数据库实施的,所以只有对那些具备可能启动一个新事务的传播行为( PROPAGATION_REQUIRED , PROPAGATION_REQUIRED_NEW , PROPAGATION_NESTED )的方法来说,才有意义。</p>    <h3>事务超时</h3>    <p>为了使应用程序很好地运行,事务不能运行太长时间。因为超时时钟会在事务开始时启动,所以只有对那些具备可能启动一个新事务的传播行为( PROPAGATION_REQUIRED , PROPAGATION_REQUIRED_NEW , PROPAGATION_NESTED )的方法来说,才有意义。</p>    <h3>事务回滚</h3>    <p>事务回滚规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有在遇到运行时期异常才回滚,而在遇到检查型异常时不会回滚。</p>    <h3>配置方式</h3>    <p>事务属性的配置方式通过以下关键字来指定:</p>    <table>     <thead>      <tr>       <th>关键字</th>       <th>含义</th>      </tr>     </thead>     <tbody>      <tr>       <td>isolation</td>       <td>指定事务的隔离级别</td>      </tr>      <tr>       <td>propagation</td>       <td>定义事务的传播规则</td>      </tr>      <tr>       <td>read-only</td>       <td>指定事务为只读</td>      </tr>      <tr>       <td>rollback-forno-rollback-for</td>       <td>rollback-for指定事务对哪些检查型异常应当回滚而不提交no-rollback-for指定事务对哪些异常应当继续执行而不回滚</td>      </tr>      <tr>       <td>timeout</td>       <td>对于长时间运行的事务定义超时时间</td>      </tr>     </tbody>    </table>    <p>XML中事务属性的配置方式如下:</p>    <pre>  <tx:advice id="txAdvice" transactionmanager="transactionManager">          <tx:attributes>              <tx:method name="*" propagation="REQUIRED" read-only="true"/>          </tx:attributes>  </tx:advice>  </pre>    <p>注解中事务属性的配置方式如下:</p>    <pre>  @Transaction(propagation=Propagation. REQUIRED,readOnly=true)  public void add(String username){      //...  }  </pre>    <h2>总结</h2>    <p>事务是企业应用开发中很重要的组成部分,他让软件变得更加健壮。他保证了全有或全无的操作。</p>    <p>Spring同时支持编码式和声明式事务管理,无论使用哪种方式进行事务管理,都应该知道与事务相关的五个属性。</p>    <h2> </h2>    <p>(全文完)</p>    <p>来自: http://www.hollischuang.com/archives/1489</p>