博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
8 -- 深入使用Spring -- 6...2 Spring支持的事务策略
阅读量:5892 次
发布时间:2019-06-19

本文共 5735 字,大约阅读时间需要 19 分钟。

      8.6.2 使用XML Schema配置事务策略

        Spring 同时支持编程式事务策略和声明式事务策略,通常都推荐采用声明式事务策略。

        ⊙ 声明式事务能大大降低开发者的代码书写量,而且声明式事务几乎不影响应用的代码。因此,无论底层事务策略如何变化,应用程序都无须任何改变。

        ⊙ 应用程序代码无须任何事务处理代码,可以更专注于业务逻辑的实现。

        ⊙ Spring则可对任何POJO的方法提供事务管理,而且Spring的声明式事务管理无须容器的支持,可在任何环境下使用。

        ⊙ 的CMT无法提供声明式回滚规则:而通过配置文件,Spring可指定事务在遇到特定异常时自动回滚。

        ⊙ 由于Spring采用AOP的方式管理事务,因此,可以在事务回滚动作中插入用户自己的动作,而不仅仅是执行系统默认的回滚。

        Spring 2.x 的XML Schema方式提供了简洁的事务配置策略,Spring 2.x提供了 tx:命名空间 来配置事务管理,tx:命名空间下提供了<tx:advice.../>元素来配置事务增强处理,一旦使用该元素配置了事务增强处理,就可直接使用<aop:advisor.../>元素启用自动代理了。

        配置<tx:advice.../>元素时除了需要transaction-manager属性指定事务管理器之外,还需要配置一个<attributes.../>子元素,该子元素里又可包含多个<method.../>子元素。

        配置<tx:advice.../>元素的重点就是配置<method.../>子元素,实际上每个<method.../>子元素都为一批方法指定了所需的事务定义,包括事务传播属性、事务隔离属性、事务超时属性、只读事务、对指定异常回滚、对指定异常不回滚等。

        配置<method.../>子元素可以指定如下属性:

          ⊙ name : 必选属性,与该事务语义关联的方法名。该属性支持使用通配符,例如:‘add*’、‘delete*’、‘get*byId’、‘update*’等。

          ⊙ propagation : 指定,该属性值可为Propagation枚举类的任一枚举值。该属性的默认值为Propagation.REQUIRED。

          ⊙ isolation : 指定事务隔离级别,该属性值可为Isolation枚举类的任一枚举值。默认值为Isolation.DEFAULT。

          ⊙ timeout : 指定事务超时的时间(以秒为单位),指定-1意味着不超时,该属性默认值是-1.

          ⊙ read-only : 指定事务是否只读。该属性的默认值是false。

          ⊙ rollback-for : 指定触发事务回滚的异常类(应使用全限定类名),该属性可指定多个异常类,多个异常类之间以英文逗号隔开。

          ⊙ no-rollback-for : 指定不触发事务回滚的异常类(应使用全限定类名),该属性可指定多个异常类,多个异常类之间以英文逗号隔开。

        <method.../>子元素的propagation属性用于指定事务传播行为,Spring支持的事务传播行为如下:

          ⊙ PROPAGATION_MANDATORY(强制的) : 要求调用方法的线程必须处于事务环境中,否则抛出异常。

          ⊙ PROPAGATION_NEVER(决不) : 不允许调用该方法的线程处于事务中,如果调用该方法的线程处于事务环境中,则抛出异常。

          ⊙ PROPAGATION_SUPPORTS(支持) : 如果当前执行线程处于事务环境中,则使用当前事务,否则不使用事务。          

          ⊙ PROPAGATION_NOT_SUPPORED (被支持的): 如果调用该方法的线程处于事务环境中,则先暂停当前事务,然后执行该方法。

          ⊙ PROPAGATION_NESTED(嵌套的) : 即使执行该方法的线程已处于事务环境中,也依然启动新的事务,方法在嵌套的事务里执行;即使执行该方法的线程并未处于事务环境中,也启动新的事务,然后执行该方法,此时与PROPAGATION_REQUIRED相同。

          ⊙ PROPAGATION_REQUIRED(必需的) : 要求在事务环境中执行该方法,如果当前执行线程已处于事务环境中,则直接调用;如果当前执行线程不处于事务环境中,则启动新的事务后执行该方法。

          ⊙ PROPAGATION_REQUIES_NEW (需求): 该方法要求在新的事务环境中执行,如果当前执行线程已处于事务环境中,则先暂停当前事务,启动新事物后执行该方法;如果当前调用线程不处于事务环境中,则启动新的事务后执行方法。

        Class : NewsDaoImpl

package edu.pri.lime._8_6_2.dao;import javax.sql.DataSource;import org.springframework.jdbc.core.JdbcTemplate;public class NewsDaoImpl implements NewsDao {    private DataSource ds;    public void setDs(DataSource ds) {        this.ds = ds;    }    @Override    public void insert(String title, String content) {        JdbcTemplate jt = new JdbcTemplate(ds);        jt.update("insert into news_inf values(null,?,?)", title, content);        // 两次插入的数据违反唯一键约束        jt.update("insert into news_inf values(null,?,?)", title, content);        // 如果没有事务控制,则第一条记录可以被插入        // 如果增加事务控制,将发现第一条记录也插不进去    }}

         XML :

        Class : SpringTest

package edu.pri.lime._8_6_2;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import edu.pri.lime._8_6_2.dao.NewsDao;import edu.pri.lime._8_6_2.dao.NewsDaoImpl;public class SpringTest {    public static void main(String[] args) {        ApplicationContext ctx = new ClassPathXmlApplicationContext("app_8_6_2_tx.xml");        // 获取事务代理Bean        NewsDao dao = ctx.getBean("newsDao", NewsDaoImpl.class);        // 执行插入操作        dao.insert("lime", "Oracle");    }}

        当使用<tx:advisor.../>为目标Bean生成事务代理之后,SpringAOP将会把负责事务操作的增强处理织入目标Bean的业务方法中。

        Spring 不仅支持对接口的代理,而且也可对具体类生成代理,只要设置proxytargetClass属性为true既可以了。如果目标Bean没有实现热河接口,proxyTargetClass属性默认被设为true,此时Spring会对具体类生成代理。当然,通常建议面向接口编程,而不要面向具体的实现类编程。

        当采用<aop:advisor.../>元素将Advice和切入点绑定时,实际上是由Spring提供的Bean后处理器完成的。Spring提供了BeanNameAutoProxyCreator、DefaultAdvisorAutoProxyCreator两个Bean后处理器,它们都可以对容器中的Bean执行后处理(为他们织入切面中包含的增强处理)。当配置<aop:advisor.../>元素时传入一个txAdvice事务增强处理,所以Bean后处理器将为所有Bean实例里匹配切入点的方法织入事务操作的增强处理。

        在这种声明式事务策略下,Spring也允许为不同的业务逻辑方法指定不同的事务策略:

        如果想让事务在遇到特定的cheched异常时自动回滚,则可借助于rollback-for属性。

        在默认情况下,只有当方法引发运行时异常和unchecked异常时,Spring事务机制才会自动回滚事务。也就是说,只有当抛出一个RuntimeException或其子类实例,或Error对象时,Spring才会自动回滚事务。如果事务方法抛出checked异常,则事务不会自动回滚。

        通过使用rollback-for属性可强制Spring遇到特定checked异常时自动回滚事务:

        如果想让Spring遇到特定runtime异常时强制不会滚事务,则可通过no-rollback-for属性来指定:

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

转载地址:http://bmnsx.baihongyu.com/

你可能感兴趣的文章