8.6.2 使用XML Schema配置事务策略

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

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

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

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

        ⊙ EJB的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 :

<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 扫描Spring的组件 -->
<context:component-scan base-package="edu.pri.lime._8_6_2.dao"/> <!-- 定义数据源Bean,使用C3P0数据源实现,并注入数据源的必要信息 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost/spring"/>
<property name="user" value="root"/>
<property name="password" value="System"/>
<property name="maxPoolSize" value="40"/>
<property name="minPoolSize" value="2"/>
<property name="initialPoolSize" value="2"/>
<property name="maxIdleTime" value="30"/>
</bean> <!-- 配置JDBC数据源的局部事务管理器,使用DataSourceTransactionManager类 -->
<!-- 该类实现了PlatformTransactionManager接口,是针对采用数据源连接的特定实现 -->
<!-- 配置DataSourceTransactionmanager时需要依赖注入DataSource的引用 -->
<bean id="transactionManager" class="org.spring.framework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 配置一个业务逻辑Bean -->
<bean id="newsDao" class="edu.pri.lime._8_6_2.dao.NewsDaoImpl">
<property name="ds" ref="dataSource"/>
</bean> <!-- 配置事务增强处理Bean,指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 用于配置详细的事务定义 -->
<tx:attributes>
<!-- 所有以get开头的方法是只读的 -->
<tx:method name="get*" read-only="true"/>
<!-- 其他方法使用默认的事务设置,指定超时时长为5秒 -->
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" timeout="5"/>
</tx:attributes>
</tx:advice> <!-- AOP配置的元素 -->
<aop:config>
<!-- 配置一个切入点,匹配edu.pri.lime._8_6_2.dao包下所有以Impl结尾的类里所有方法的执行 -->
<aop:pointcut expression="execution(* edu.pri.lime._8_6_2.dao.*Impl.*(..))" id="myPointcut"/>
<!-- 指定在myPointcut切入点应用txAdvice事务增强处理 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
</aop:config>
</beans>

        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也允许为不同的业务逻辑方法指定不同的事务策略:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 扫描Spring的组件 -->
<context:component-scan base-package="edu.pri.lime._8_6_2.dao"/> <!-- 定义数据源Bean,使用C3P0数据源实现,并注入数据源的必要信息 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost/spring"/>
<property name="user" value="root"/>
<property name="password" value="System"/>
<property name="maxPoolSize" value="40"/>
<property name="minPoolSize" value="2"/>
<property name="initialPoolSize" value="2"/>
<property name="maxIdleTime" value="30"/>
</bean> <!-- 配置JDBC数据源的局部事务管理器,使用DataSourceTransactionManager类 -->
<!-- 该类实现了PlatformTransactionManager接口,是针对采用数据源连接的特定实现 -->
<!-- 配置DataSourceTransactionmanager时需要依赖注入DataSource的引用 -->
<bean id="transactionManager" class="org.spring.framework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!-- 配置一个业务逻辑Bean -->
<bean id="newsDao" class="edu.pri.lime._8_6_2.dao.NewsDaoImpl">
<property name="ds" ref="dataSource"/>
</bean> <!-- 配置两个事务增强处理 -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice> <tx:advice id="noTxAdvice">
<tx:attributes>
<tx:method name="*" propagation="NEVER"/>
</tx:attributes>
</tx:advice> <aop:config>
<!-- 配置一个切入点,匹配userService Bean 中所有方法的执行 -->
<aop:pointcut expression="bean(userService)" id="txOperation"/>
<!-- 配置一个切入点,匹配包下所有以Impl结尾的类中所有方法的执行 -->
<aop:pointcut expression="execution(* edu.pri.lime._8_6_2.dao.*Impl.*(..))" id="noTxOperation"/>
<!-- 将txOperation切入点和defaultTxAdvice切面绑定在一起 -->
<aop:advisor advice-ref="defaultTxAdvice" pointcut-ref="txOperation"/>
<!-- 将noTxOperation切入点和noTxAdvice切面绑定在一起 -->
<aop:advisor advice-ref="noTxAdvice" pointcut-ref="noTxOperation"/>
</aop:config> <!-- 配置第一个业务逻辑Bean,该Bean的名字为userService,匹配txOperation切入点将被织入defaultTxAdvice切面里的增强处理 -->
<bean id="userService" class=""></bean>
<!-- 配置第二个业务逻辑Bean,实现类位于包下,将被织入noTxAdvice切面里的增强处理 -->
<bean id="anotherFooService" class=""/>
</beans>

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

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

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

<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"
rollback-for="exception.NoItemException" />
<tx:method name="*" />
</tx:attributes>
</tx:advice> </beans>

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

<?xml version="1.0" encoding="UTF-8"?>
<!-- Spring 配置文件的根元素,使用Spring-beans-4.0.xsd语义约束 -->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"
no-rollback-for="exception.AuctionException" />
<tx:method name="*" />
</tx:attributes>
</tx:advice> </beans>

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

8 -- 深入使用Spring -- 6...2 Spring支持的事务策略的更多相关文章

  1. 8 -- 深入使用Spring -- 6...1 Spring支持的事务策略

    8.6.1 Spring支持的事务策略 JTA.JDBC.Hibernate Java EE应用的传统事务有两种策略:全局事务和局部事务.全局事务由应用服务器管理,需要底层服务器的JTA(Java T ...

  2. 8.Spring对JDBC的支持和事务

    1.Spring对JDBC的支持 DAO : Spring中对数据访问对象(DAO)的支持旨在简化Spring与数据访问技术的操作,使JDBC.Hibernate.JPA和JDO等采用统一的方式访问 ...

  3. java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板

    java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring   本文主要介绍利用JavaMailS ...

  4. Spring AOP和AspectJ支持

    学了Spring之后发现我都不知道java为何物-- 在这一章中有好几节,讲的切面编程 第一节:在项目中启用Spring的AspectJ注解支持 第二节:用AspectJ注解声明aspect 第三节: ...

  5. Spring使用拦截器支持国际化(转)

    Spring使用拦截器支持国际化很方便,使用时只需要两个步骤: 一.spring配置 具体配置方式如下: <!-- 资源文件绑定器,文件名称:messages.properties(没有找到时的 ...

  6. Spring对远程服务的支持

    Java程序有以下的远程调用技术选择: 远程过程调用(RPC)是同步的,客户端在服务器端返回结果之前将一直被阻塞. 各种技术适用的场景如下: 典型的RMI开发的过程如下: 定义一个接口,用于客户端和服 ...

  7. 1.Spring对JDBC整合支持

    1.Spring对JDBC整合支持 Spring对DAO提供哪些支持 1)Spring对DAO异常提供统一处理 2)Spring对DAO编写提供支持的抽象类 3)提高编程效率,减少DAO编码量 Spr ...

  8. [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction

    1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...

  9. Spring Boot 添加JSP支持【转】

    Spring Boot 添加JSP支持 大体步骤: (1)            创建Maven web project: (2)            在pom.xml文件添加依赖: (3)     ...

随机推荐

  1. 【dedecms网站安全】如何防止dedecms网站被DDos攻击

    [dedecms网站安全]如何防止dedecms网站被DDos攻击 第一步:进入后台,系统->添加新变量变量名称:cfg_anquan_cc 变量类型:布尔(Y/N)  参数说明:是否开启防CC ...

  2. spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor

    更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...

  3. How to modify analog output range of Arduino Due

    Voltage Translation for Analog to Digital Interface ADC How to modify analog output range of Arduino ...

  4. 四种常见 Git 工作流比较

    BY 童仲毅(geeeeeeeeek@github) 这是一篇在原文(BY atlassian)基础上演绎的译文.除非另行注明,页面上所有内容采用知识共享-署名(CC BY 2.5 AU)协议共享. ...

  5. autorelease' is unavailable

    ARC forbids explicit message send of'release' 'release' is unavailable: not available inautomatic re ...

  6. 【CSS Demo】纯 CSS 打造 Flow-Steps 导航

    low-Steps 导航效果常用于需要表示执行步骤的交互页面,效果如下: 步骤一 步骤二 步骤三   通常使用图片来实现 Flow-Steps 效果,但此方法的灵活性不足,当内容变化较大时就可能需要重 ...

  7. 通过action传过来的值在option获取进行验证

    通过action传过来的值在option获取进行验证的方法: for(var i=0;i<document.getElementById("ufacilityType").o ...

  8. Json解析包FastJson使用

    阿里巴巴FastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征:速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java Json parser. ...

  9. js 引擎 和 html 渲染引擎

  10. 【C语言】符号优先级

    一. 问题的引出 今天看阿里的笔试题,看到一个非常有意思的题目,但是很容易出错. 题目:如下函数,在32bit系统foo(2^31-3)的值是: Int foo(int x) { return x&a ...