spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作。今天一起学习一下Spring的事务管理。Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。 DataSource、TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用hibernate进行数据访问时,DataSource实际为SessionFactory,TransactionManager的实现为HibernateTransactionManager。 下面一起看看三种声明式事务的具体配置:

 

公共配置

  1. <!-- 配置sessionFactory -->
  2. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  3. <property name="configLocation">
  4. <value>classpath:config/hibernate.cfg.xml</value>
  5. </property>
  6. <property name="packagesToScan">
  7. <list>
  8. <value>com.entity</value>
  9. </list>
  10. </property>
  11. </bean>
  12. <!-- 配置事务管理器(声明式的事务) -->
  13. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  14. <property name="sessionFactory" ref="sessionFactory"></property>
  15. </bean>
  16. <!-- 配置DAO -->
  17. <bean id="userDao" class="com.dao.UserDaoImpl">
  18. <property name="sessionFactory" ref="sessionFactory"></property>
  19. </bean>

第一种,使用tx标签方式

  1. <!-- 第一种配置事务的方式 ,tx-->
  2. <tx:advice id="txadvice" transaction-manager="transactionManager">
  3. <tx:attributes>
  4. <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
  5. <tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception" />
  6. <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
  7. <tx:method name="*" propagation="REQUIRED" read-only="true"/>
  8. </tx:attributes>
  9. </tx:advice>
  10. <aop:config>
  11. <aop:pointcut id="daoMethod" expression="execution(* com.dao.*.*(..))"/>
  12. <aop:advisor pointcut-ref="daoMethod" advice-ref="txadvice"/>
  13. </aop:config>

expression="execution(* com.dao.*.*(..))"
其中第一个*代表返回值,第二*代表dao下子包,第三个*代表方法名,“(..)”代表方法参数。

第二种,使用代理方式

  1. <!-- 第二种配置事务的方式 ,代理-->
  2. <bean id="transactionProxy"
  3. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
  4. <property name="transactionManager" ref="transactionManager"></property>
  5. <property name="transactionAttributes">
  6. <props>
  7. <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
  8. <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
  9. <prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
  10. <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
  11. </props>
  12. </property>
  13. </bean>
  14. <bean id="userDao" parent="transactionProxy">
  15. <property name="target">
  16. <!-- 用bean代替ref的方式-->
  17. <bean class="com.dao.UserDaoImpl">
  18. <property name="sessionFactory" ref="sessionFactory"></property>
  19. </bean>
  20. </property>
  21. </bean>

将transactionProxy的abstract属性设置为"true",然后将具体的Dao的parent属性设置为"transactionProxy",可以精简代码。

第三种,使用拦截器

  1. <!-- 第三种配置事务的方式,拦截器 (不常用)-->
  2. <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
  3. <property name="transactionManager" ref="transactionManager"></property>
  4. <property name="transactionAttributes">
  5. <props>
  6. <prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
  7. <prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
  8. <prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
  9. <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
  10. </props>
  11. </property>
  12. </bean>
  13. <bean id="proxyFactory" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  14. <property name="interceptorNames">
  15. <list>
  16. <value>transactionInterceptor</value>
  17. </list>
  18. </property>
  19. <property name="beanNames">
  20. <list>
  21. <value>*Dao</value>
  22. </list>
  23. </property>
  24. </bean>

Spring事务类型详解:

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

<tx:method/> 有关的设置

属性 是否需要? 默认值 描述
name  

与事务属性关联的方法名。通配符(*)可以用来指定一批关联到相同的事务属性的方法。如:'get*''handle*''on*Event'等等。

propagation REQUIRED 事务传播行为
isolation DEFAULT 事务隔离级别
timeout -1 事务超时的时间(以秒为单位)
read-only false 事务是否只读?
rollback-for  

将被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException'

no-rollback-for  

 被触发进行回滚的 Exception(s);以逗号分开。 如:'com.foo.MyBusinessException,ServletException'

采用注解的方式,需要注意的是,使用注解的方式需要在Spring的配置文件中加入一句话:<context:annotation-config />,其作用是开启注解的方式。具体配置如下:

  1. <!--开启注解方式-->
  2. <context:annotation-config />
  3. <!-- 配置sessionFactory -->
  4. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
  5. <property name="configLocation">
  6. <value>classpath:config/hibernate.cfg.xml</value>
  7. </property>
  8. <property name="packagesToScan">
  9. <list>
  10. <value>com.entity</value>
  11. </list>
  12. </property>
  13. </bean>
  14. <!-- 配置事务管理器 -->
  15. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  16. <property name="sessionFactory" ref="sessionFactory"></property>
  17. </bean>
  18. <!-- 第四种配置事务的方式,注解 -->
  19. <tx:annotation-driven transaction-manager="transactionManager"/>

注解文件:

  1. package com.dao;
  2. import org.springframework.orm.hibernate3.HibernateTemplate;
  3. import org.springframework.transaction.annotation.Propagation;
  4. import org.springframework.transaction.annotation.Transactional;
  5. import com.entity.User;
  6. @Transactional
  7. public class UserDaoImpl_BAK extends HibernateTemplate {
  8. @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
  9. public void addUser(User user) throws Exception {
  10. this.save(user);
  11. }
  12. @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
  13. public void modifyUser(User user) {
  14. this.update(user);
  15. }
  16. @Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
  17. public void delUser(String username) {
  18. this.delete(this.load(User.class, username));
  19. }
  20. @Transactional(readOnly=true)
  21. public void selectUser() {
  22. }
  23. }

类头的@Transactional为默认事务配置,如方法没有自己的事务类型,则按默认事务,如有自己的配置,则按自己的配置。

以上四种配置方式最常用的还是第一、二种,第三种是比较老旧的方式,而注解的方式不太适合比较大的项目,用于简单的小项目还是很好的,其特点就是简单明了。每种方法都有每种方法的特点跟适用的环境,没有绝对的好与坏,只不过前两种在实际的工作当中用的更多一些。

转:Spring事务管理的更多相关文章

  1. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  2. spring事务管理器设计思想(二)

    上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...

  3. spring事务管理器设计思想(一)

    在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...

  4. 事务管理(下) 配置spring事务管理的几种方式(声明式事务)

    配置spring事务管理的几种方式(声明式事务) 概要: Spring对编程式事务的支持与EJB有很大的区别.不像EJB和Java事务API(Java Transaction API, JTA)耦合在 ...

  5. Spring事务管理器的应对

    Spring抽象的DAO体系兼容多种数据访问技术,它们各有特色,各有千秋.像Hibernate是非常优秀的ORM实现方案,但对底层SQL的控制不太方便:而iBatis则通过模板化技术让你方便地控制SQ ...

  6. Spring事务管理(转)

    1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是 ...

  7. [Spring框架]Spring 事务管理基础入门总结.

    前言:在之前的博客中已经说过了数据库的事务, 不过那里面更多的是说明事务的一些锁机制, 今天来说一下Spring管理事务的一些基础知识. 之前的文章: [数据库事务与锁]详解一: 彻底理解数据库事务一 ...

  8. Spring 事务管理 01 ——

    目录: 参考: 1.Spring 事务管理高级应用难点剖析: 第 1 部分

  9. Spring 事务管理原理探究

    此处先粘贴出Spring事务需要的配置内容: 1.Spring事务管理器的配置文件: 2.一个普通的JPA框架(此处是mybatis)的配置文件: <bean id="sqlSessi ...

  10. Spring 事务管理高级应用难点剖析--转

    第 1 部分 http://www.ibm.com/search/csass/search/?q=%E4%BA%8B%E5%8A%A1&sn=dw&lang=zh&cc=CN& ...

随机推荐

  1. 用OpenGL画线

    . 两点之间的连线称之为线段,在屏幕上显示线段放在现在已经不是稀奇的事情,大多数高级图形API都可以轻松实现,我尝试用OpenGL画线,在这里记录一下收获. . OpenGL这个级别的图形API,通常 ...

  2. JSP——底层原理

    都知道jsp就是在HTML文件中写java代码,以实现动态页面的效果,但是这种动态是如何实现的呢?今天就在研究一下. 首先,我写了一个简单的jsp文件: <%@page import=" ...

  3. Appium+python自动化(三十九)-Appium自动化测试框架综合实践 - 代码实现(超详解)

    简介 经过一段时间的准备,完善的差不多了,继续分享有关Appium自动化测试框架综合实践.想必小伙伴们有点等不及了吧! driver配置封装 kyb_caps.yaml 配置表 参考代码 platfo ...

  4. 比较器中的comparing方法以及涉及到的知识

    今天在学习Java核心技术集合程序清单9-3时遇到了问题. 代码如下 public class TreeSetTest { public static void main(String[] args) ...

  5. [Error]使用了未经检查或不安全的操作...

    编译错误注: MethodReflect.java使用了未经检查或不安全的操作.注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译. 解决:在类前面加入下面一句解决 @Suppr ...

  6. 力扣(LeetCode)Excel表列名称 个人题解

    给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如, 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -> AA 28 -> ...

  7. 64位手机部署centos

    在64位处理器的手机上部署centos会有下面的困难. 1. 没有现成的aarch64的rootfs. 2. termux没有rpm2cpio进行部署. 3. armv8*不会被centos识别为aa ...

  8. B0宏

    在编译android平台用的ffmpeg时,抛出这样一个错误: 这句代码怎么看都找出有毛病,为什么B0会报错? 翻看aaccoder.c,也没有发现问题.为什么B0就成了一个常量数字,这里只有一个可能 ...

  9. android逆向总结

    首先项目里的java文件,以及项目引用到的第三方jar或aar包里面的class,统统都编译成classes.dex放在apk包的根目录,项目的资源目录和AndroidManifest.xml被处理生 ...

  10. [转发]CSR 量产 烧录 软件

    蓝牙量产软件主要是为了应对蓝牙设备在批量生产时的一些如固件下载,地址下载,名字修改,以及一些辅助测试和检验功能. 目前,CSR推出的蓝牙芯片按照存储介质以及可编程与否分为两大类:ROM版本和Flash ...