5.1 Spring事务管理概述

5.11 事务管理的核心接口

在Spring的所有jar包中,有一个名spring-tx-4.3.6RELEAS的jar包,是提供事务管理的依赖包。在该包的org.springframework.transaction包中,三个核心接口文件分别是PlatformTransactionManagerTransactionDefinitionTransactionStatus

1.PlatfromTransactionManager

PlatfromTransactionManager接口是Spring提供的平台事务管理器,主要用于管理事务。有3个事务操作的方法:

TransactionStatus getTransaction( TransactionDefinition definition ):用于获取事务状态信息

void commit( TransactionStatus status ):提交事务

void rollback( Transaction status ):回滚事务

PlatformTransactionManager接口只是代表事务管理的接口,并不知道底层是如何管理事务的,具体如何管理事务则由它的实现类来完成。该接口常见的几个实现类如下:

(1)、用于配置JDBC数据源的事务管理器:
org.springframework.jdbc.datasource.DataSourceTransactionManager
(2)、用于配置Hibernate的事务管理器:
org.springframework.orm.hibernate4.HibernateTransactionManager
(3)、用于配置全局事务管理器:
org.springframework.transaction.jta.JtaTransactionManager

当底层采用不同的持久层技术时,系统只需使用不同的实现类。

2.TransactionDefinition

事务定义(描述)的对象,该对象中定义了事务规则,并提供获取事务相关信息的方法,具体如下:

String getName():获取事务对象名称

int getlsolationLevel:获取事务的隔离级别

int getPropagationBehavior():获取事务的传播行为

int getTimeout():获取事务的超时时间

boolean isReadOnly():获取事务的是否只读

传播行为:指在同一个方法中,不同操作前后所使用的事务。传播行为有很多种:

传播行为可以控制是否需要创建事务以及如何创建事务,查询不影响数据的改变,不需要事务管理;插入、更新和删除需要事务管理。如果没有指定事务的传播行为,Spring默认传播行为是REQUIRED(required)

3.TransactionStatus

TransactionStatus接口是事务的状态,它描述了某一时间点上事务的状态信息,该接口有6个方法:

void flush():刷新事务

boolean hasSavepoint():获取是否存在保存点

boolean isCompleted():获取事务是否完成

boolean isNewTransaction():获取是否是新事物

boolean isRollbackOnly():获取是否回滚

void setRollbackOnly():设置事务回滚

5.12 事务管理的方式:

传统的编程式事务管理:通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚

声明式事务管理:通过AOP技术实现的事务管理,主要思想是将事务管理作为一个“切面”代码单独编写,然后通过AOP技术将管理“切面”代码织入到业务目标类中。

5.2 声明式事务管理

5.21 基于XML方式的声明式事务

tx命名空间下提供了<tx:advice>元素来配置事务的通知(增强处理)。当使用<tx:advice>元素配置了事务的增强处理后,就可以通过编写AOP配置,让Spring自动对目标生成代理。

配置<tx:advice>元素时,通常需要指定id和transaction-manager属性。transaction-manager属性用于指定事务管理器。除此之外,还需要配置一个<tx:attributes>子元素,该子元素可以通过配置多个<tx:method>子元素来配置执行事务的细节。

转账方法编写:

  1. /**
  2. * 转账
  3. * inUser:收款人
  4. * outUser:汇款人
  5. * money:收款金额
  6. */
  7. public void transfer(String outUser, String inUser, Double money) {
  8. // 收款时,收款用户的余额=现有余额+所汇金额
  9. this.jdbcTemplate.update("update account set balance = balance +? "
  10. + "where username = ?",money, inUser);
  11. // 模拟系统运行时的突发性问题
  12. int i = /;
  13. // 汇款时,汇款用户的余额=现有余额-所汇金额
  14. this.jdbcTemplate.update("update account set balance = balance-? "
  15. + "where username = ?",money, outUser);
  16. }

XML文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:context="http://www.springframework.org/schema/context"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
  9. http://www.springframework.org/schema/tx
  10. http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
  11. http://www.springframework.org/schema/context
  12. http://www.springframework.org/schema/context/spring-context-4.3.xsd
  13. http://www.springframework.org/schema/aop
  14. http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  15.  
  16. <!-- 1.配置数据源 -->
  17. <bean id="dataSource222"
  18. class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  19.  
  20. <!--数据库驱动 -->
  21. <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  22.  
  23. <!--连接数据库的url -->
  24. <property name="url" value="jdbc:mysql://localhost/spring" />
  25.  
  26. <!--连接数据库的用户名 -->
  27. <property name="username" value="root" />
  28.  
  29. <!--连接数据库的密码 -->
  30. <property name="password" value="****" />
  31. </bean>
  32.  
  33. <!-- 2.配置JDBC模板 -->
  34. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  35.  
  36. <!-- 默认必须使用数据源 -->
  37. <property name="dataSource" ref="dataSource222" />
  38.  
  39. </bean>
  40.  
  41. <!--3.定义id为accountDao的Bean -->
  42. <bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl">
  43.  
  44. <!-- 将jdbcTemplate注入到AccountDao实例中 -->
  45. <property name="jdbcTemplate" ref="jdbcTemplate" />
  46. </bean>
  47.  
  48. <!-- 4.事务管理器,依赖于数据源 -->
  49. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  50.  
  51. <property name="dataSource" ref="dataSource222" />
  52. </bean>
  53.  
  54. <!-- 5.编写通知:对事务进行增强(通知),需要编写对切入点和具体执行事务细节 -->
  55. <tx:advice id="txAdvice123" transaction-manager="transactionManager">
  56. <tx:attributes>
  57. <!-- name:*表示任意方法名称,传播行为,隔离级别,是否只读-->
  58. <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
  59. </tx:attributes>
  60. </tx:advice>
  61.  
  62. <!-- 6.编写AOP,让spring自动对目标生成代理,需要使用AspectJ的表达式 -->
  63. <aop:config>
  64. <!-- 切入点 -->
  65. <aop:pointcut expression="execution(* com.itheima.jdbc.*.*(..))"
  66. id="txPointCut111" />
  67. <!-- 切面:将切入点与通知整合 -->
  68. <aop:advisor advice-ref="txAdvice123" pointcut-ref="txPointCut111" />
  69. </aop:config>
  70. </beans>

测试类:获取实例,调用方法,常规操作

  1. @Test///基于XML方式的声明式事务
  2. public void xmlTest(){
  3. ApplicationContext applicationContext =
  4. new ClassPathXmlApplicationContext("applicationContext.xml");
  5.  
  6. // 获取AccountDao实例
  7. AccountDao accountDao =
  8. (AccountDao)applicationContext.getBean("accountDao");
  9.  
  10. // 调用实例中的转账方法
  11. accountDao.transfer("Jack", "Rose", 100.0);
  12.  
  13. // 输出提示信息
  14. System.out.println("转账成功!");
  15. }

5.22 基于Annotation(注解)方式的声明式事务

两个套路

1.在Spring容器中注册事务注解驱动:

  1. <tx:annotation-driven transaction-manager="transactionManager"/>

XML文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:context="http://www.springframework.org/schema/context"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
  9. http://www.springframework.org/schema/tx
  10. http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
  11. http://www.springframework.org/schema/context
  12. http://www.springframework.org/schema/context/spring-context-4.3.xsd
  13. http://www.springframework.org/schema/aop
  14. http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
  15. <!-- 1.配置数据源 -->
  16. <bean id="dataSource"
  17. class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  18.  
  19. <!--数据库驱动 -->
  20. <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  21.  
  22. <!--连接数据库的url -->
  23. <property name="url" value="jdbc:mysql://localhost/spring" />
  24.  
  25. <!--连接数据库的用户名 -->
  26. <property name="username" value="root" />
  27.  
  28. <!--连接数据库的密码 -->
  29. <property name="password" value="17251104238" />
  30. </bean>
  31.  
  32. <!-- 2.配置JDBC模板 -->
  33. <bean id="jdbcTemplate"
  34. class="org.springframework.jdbc.core.JdbcTemplate">
  35.  
  36. <!-- 默认必须使用数据源 -->
  37. <property name="dataSource" ref="dataSource" />
  38.  
  39. </bean>
  40.  
  41. <!--3.定义id为accountDao的Bean -->
  42. <bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl">
  43. <!-- 将jdbcTemplate注入到AccountDao实例中 -->
  44. <property name="jdbcTemplate" ref="jdbcTemplate" />
  45. </bean>
  46.  
  47. <!-- 4.事务管理器,依赖于数据源 -->
  48. <bean id="transactionManager" class=
  49. "org.springframework.jdbc.datasource.DataSourceTransactionManager">
  50. <property name="dataSource" ref="dataSource" />
  51. </bean>
  52.  
  53. <!-- 5.注册事务管理器驱动 -->
  54. <tx:annotation-driven transaction-manager="transactionManager"/>
  55.  
  56. </beans>

2.在方法transfer()前加注解:

  1. @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)

方法:

  1. @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
  2. public void transfer(String outUser, String inUser, Double money)
  3. {
  4. // 收款时,收款用户的余额=现有余额+所汇金额
  5. this.jdbcTemplate.update("update account set balance = balance +? "
  6. + "where username = ?",money, inUser);
  7.  
  8. // 模拟系统运行时的突发性问题
  9. //int i = 1/0;
  10. // 汇款时,汇款用户的余额=现有余额-所汇金额
  11. this.jdbcTemplate.update("update account set balance = balance -? "
  12. + "where username = ?",money, outUser);
  13. }

第5章 Spring的事务管理的更多相关文章

  1. 深入Spring:自定义事务管理

    转自: http://www.jianshu.com/p/5347a462b3a5 前言 上一篇文章讲了Spring的Aop,这里讲一下Spring的事务管理,Spring的事务管理是建立在Aop的基 ...

  2. Spring AOP事务管理(使用切面把事务管理起来)

    在<Spring Transaction 分析事务属性(事务的基本概念.配置)>基础上 http://blog.csdn.net/partner4java/article/details/ ...

  3. Spring的事务管理

    事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 ...

  4. spring笔记--事务管理之声明式事务

    事务简介: 事务管理是企业级应用开发中必不可少的技术,主要用来确保数据的完整性和一致性, 事务:就是一系列动作,它们被当作一个独立的工作单元,这些动作要么全部完成,要么全部不起作用. Spring中使 ...

  5. Spring应用——事务管理

    事务基础:请参看:http://www.cnblogs.com/solverpeng/p/5720306.html 一.Spring 事务管理 1.前提:事务管理器 在使用 Spring 声明式事务管 ...

  6. spring+mybatis事务管理

    spring+mybatis事务管理 最近在和朋友做一个项目,考虑用springmvc+mybatis来做,之前在公司工作吧,对于数据库这块的配置也有人再弄,最近因为这个项目,我就上网学习了一些关于数 ...

  7. spring,mybatis事务管理配置与@Transactional注解使用[转]

    spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述事务管理对于企业应用来说是至关 ...

  8. Spring高级事务管理难点剖析

    1Spring事务传播行为 所谓事务传播行为就是多个事务方法相互调用时,事务如何在这些方法间传播.Spring支持7种事务传播行为 PROPAGATION_REQUIRED(加入已有事务) 如果当前没 ...

  9. CSDN上看到的一篇有关Spring JDBC事务管理的文章(内容比较全) (转)

    JDBC事务管理 Spring提供编程式的事务管理(Programmatic transaction manage- ment)与声明式的事务管理(Declarative transaction ma ...

随机推荐

  1. [转帖]中国 GPL 诉讼第一案:关于 GPL 问题的探讨

    中国 GPL 诉讼第一案:关于 GPL 问题的探讨 https://linux.cn/article-11683-1.html 2019 年 11 月初,数字天堂(北京)网络技术有限公司(下称:数字天 ...

  2. Visual Studio 重命名项目名

    1. 打开VS Studio,重命名项目 2. 重命名对应的项目文件夹,并重命名项目文件夹下的这两个文件名: 3. 用记事本打开解决方案,修改对应的项目名字和路径 未完 ...... 点击访问原文(进 ...

  3. ubuntu 18 docker 搭建Prometheus+Grafana

    Prometheus(普罗米修斯)是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的.随着发展,越来越多公司和组织接受采用Prometheus,社会也 ...

  4. 「NOI2015」小园丁与老司机

    「NOI2015」小园丁与老司机 要不是这道码农题,去年就补完了NOI2015,其实两问都比较simple,但是写起来很恶心. 先解决第一问,记 \(dp[i]\) 表示老司机到达第 \(i\) 棵树 ...

  5. Codeforces 878 E. Numbers on the blackboard

    Codeforces 878 E. Numbers on the blackboard 解题思路 有一种最优策略是每次选择最后面一个大于等于 \(0\) 的元素进行合并,这样做完以后相当于给这个元素乘 ...

  6. SQL系列(十二)—— insert update delete

    前言 这个系列的前面都一直在介绍查询select.但是SQL中十分广泛,按对数据的不同处理可以分为: DML:全称Data Manipulation Language,从名字上可以看出,DML是对数据 ...

  7. Mysql——查看数据库,表占用磁盘大小

    .查询所有数据库占用磁盘空间大小 select TABLE_SCHEMA, concat(,),' MB') as data_size, concat(,),'MB') as index_size f ...

  8. java中Math类

    Math类 Math类是一个很有用的数学帮助类,使用也非常简单,这个类比较特殊,首先他和String类一样都是用final修饰,所以不能有子类,还有就是它的构造方法是私有的,也就是我们不能通过new的 ...

  9. Nginx配置gzip.md

    参考 入门系列之在Nginx配置Gzip gzip是一种流行的数据压缩程序.您可以使用gzip压缩Nginx实时文件.这些文件在检索时由支持它的浏览器解压缩,好处是web服务器和浏览器之间传输的数据量 ...

  10. spring boot整合spring Data JPA和freemarker

    1.spring Data JPA简介 是一个替代hibernate的一个作用于数据库的框架. 2.整合 1.导入依赖 <dependency> <groupId>org.sp ...