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;}@Overridepublic 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");// 获取事务代理BeanNewsDao 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>

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

啦啦啦

转载于:https://www.cnblogs.com/ClassNotFoundException/p/6596819.html

8 -- 深入使用Spring -- 6...2 Spring支持的事务策略相关推荐

  1. Java缓存学习之五:spring 对缓存的支持

    (注意标题,Spring对缓存的支持 这里不单单指Ehcache ) 从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache ...

  2. Spring对AOP的支持

     Spring对AOP的支持<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" ...

  3. 在controller中调用指定参数给指定表单_第005课:Spring Boot 中MVC支持

    Spring Boot 的 MVC 支持主要介绍实际项目中最常用的几个注解,包括 @RestController. @RequestMapping.@PathVariable.@RequestPara ...

  4. Spring对JNDI的支持方法

    Spring对JNDI的支持 Spring中对于JNDI的访问,提供了便捷的方法,在Spring的org.springframework.jndi包中包含了所有的类.其中提供了一下核心类: 1)Jnd ...

  5. Spring对java模块化支持_Spring项目对JDBC的支持和基本使用

    欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...

  6. Spring Cloud Gateway 原生支持接口限流该怎么玩

    关于pig: 基于Spring Cloud.oAuth2.0开发基于Vue前后分离的开发平台,支持账号.短信.SSO等多种登录,提供配套视频开发教程. 关于 Spring Cloud Gateway ...

  7. 由openSession、getCurrentSession和HibernateDaoSupport浅谈Spring对事物的支持

    由openSession.getCurrentSession和HibernateDaoSupport浅谈Spring对事物的支持 Spring和Hibernate的集成的一个要点就是对事务的支持,op ...

  8. 如何理解Spring对缓存的支持

    1.Spring缓存机制的理解 在Spring缓存机制中,包括了两个方面的缓存操作:1.缓存某个方法返回的结果:2.在某个方法执行前或后清空缓存. 下面写两个类来模拟Spring的缓存机制: pack ...

  9. CORS跨域资源共享(二):详解Spring MVC对CORS支持的相关类和API【享学Spring MVC】

    每篇一句 重构一时爽,一直重构一直爽.但出了问题火葬场 前言 上篇文章通过我模拟的跨域请求实例和结果分析,相信小伙伴们都已经80%的掌握了CORS到底是怎么一回事以及如何使用它.由于Java语言中的w ...

最新文章

  1. post传值php取不到数据,post请求中的参数形式和form-data提交数据时取不到的问题...
  2. 人人都来写算法 之 快速排序
  3. 每周分享第7期(2019.5.18)
  4. SQL语句之left join、right join、inner join的区别
  5. sequelize连接mysql_node.js通过Sequelize 连接MySQL
  6. 隐藏画质代码_优秀的模糊测试代码是如何炼成的?
  7. 除了 Tensorflow、PyTorch ,还有哪些深度学习框架值得期待?
  8. (15)FPGA面试题存储器资源区别
  9. Spring Boot 核心原理与源码解析 - 目录
  10. python操控chrome抓网页
  11. r语言结构方程模型可视化_R语言时间序列分析(二):ts对象及其可视化
  12. hrbust/哈理工oj 1809 再就业【状压dp】
  13. 从阿尔法元的诞生看终极算法的可能性
  14. Java——单例模式:饿汉、懒汉模式
  15. java 农历公历转换_Java怎样编程实现农历和阳历转换?
  16. 新思课堂C语言答案,新思课堂APP最新版下载_新思课堂APP官方版1.6.8下载_QQ下载站...
  17. Carte+kettle+mysql性能问题定位分析记录
  18. mysql 8.0 用户修改为简单密码
  19. Java的泛型---(英雄联盟集合嵌套案例)
  20. 字典树学习 根据前缀词根建立字典树

热门文章

  1. 经验的总结,需要记录。
  2. UNetbootin | 轻松制作Linux/BSD安装引导U盘
  3. magento 2 引用 css,Magento2在Phtml文件中调用显示静态块
  4. perl oracle ppm,Perl图形化包管理工具PPM学习使用笔记
  5. springboot整合websocket进行消息推送
  6. python透明图片合并_如何使用PIL将透明png图像与另一个图像合并
  7. C语言查看tuxedo队列长度,tuxedo的常用启、停、参数讲解、日志查看
  8. 开源GIS(九)——openlayers中简单要素的添加与geojson数据修改添加
  9. VirtualBox扩容失败-Progress state: VBOX_E_NOT_SUPPORTED
  10. oracle服务器文件路径,ORACLE 数据库如何通过修改数据文件路径进行数据迁移