本文源码:GitHub·点这里 || GitEE·点这里

一、事务管理简介

1、事务基本概念

一组业务操作ABCD,要么全部成功,要么全部不成功。

2、特性:ACID

原子性:整体

一致性:完成

隔离性:并发

持久性:结果

3、隔离问题

脏读:一个事务读到另一个事务没有提交的数据

不可重复读:一个事务读到另一个事务已提交的数据(update)

虚读(幻读):一个事务读到另一个事务已提交的数据(insert)

4、隔离级别

read uncommitted:读未提交。

read committed:读已提交。解决脏读。

repeatable read:可重复读。解决:脏读、不可重复读。

serializable :串行化。都解决,单事务。

二、Spring管理事务

1、顶级接口



1)PlatformTransactionManager

平台事务管理器,spring要管理事务,必须使用事务管理器进行事务配置时,必须配置事务管理器。

2)TransactionDefinition

事务详情(事务定义、事务属性),spring用于确定事务具体详情,

例如:隔离级别、是否只读、超时时间 等

进行事务配置时,必须配置详情。spring将配置项封装到该对象实例。

3)TransactionStatus

事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。

spring底层根据状态进行相应操作。

2、事务状态

3、事务定义

  1. PROPAGATION_REQUIRED , required , 必须 【默认值】
  2. 支持当前事务,A如果有事务,B将使用该事务。
  3. 如果A没有事务,B将创建一个新的事务。
  4. PROPAGATION_SUPPORTS supports ,支持
  5. 支持当前事务,A如果有事务,B将使用该事务。
  6. 如果A没有事务,B将以非事务执行。
  7. PROPAGATION_MANDATORYmandatory ,强制
  8. 支持当前事务,A如果有事务,B将使用该事务。
  9. 如果A没有事务,B将抛异常。
  10. PROPAGATION_REQUIRES_NEW requires_new ,必须新的
  11. 如果A有事务,将A的事务挂起,B创建一个新的事务
  12. 如果A没有事务,B创建一个新的事务
  13. PROPAGATION_NOT_SUPPORTED not_supported ,不支持
  14. 如果A有事务,将A的事务挂起,B将以非事务执行
  15. 如果A没有事务,B将以非事务执行
  16. PROPAGATION_NEVER never,从不
  17. 如果A有事务,B将抛异常
  18. 如果A没有事务,B将以非事务执行
  19. PROPAGATION_NESTED nested ,嵌套
  20. AB底层采用保存点机制,形成嵌套事务。
  21. 掌握:PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_NESTED

三、SpringBoot2.0管理事务

基于转账的案例演示,基于druid连接池配置。druid连接池在文章。

  1. SpringBoot2.0 基础案例(07):集成Druid连接池,配置监控界面

1、新建转账表

  1. CREATE TABLE account(
  2. id INT PRIMARY KEY AUTO_INCREMENT,
  3. username VARCHAR(50),
  4. money INT
  5. )ENGINE=InnoDB DEFAULT CHARSET=utf8;
  6. INSERT INTO account(username,money) VALUES('jack','10000');
  7. INSERT INTO account(username,money) VALUES('rose','10000');
  8. SELECT * FROM account;

2、基于事务手动管理器

该配置用于测试事务的手动管理。

  1. /**
  2. * 事物管理器
  3. */
  4. @Bean(name = "transactionManager")
  5. public PlatformTransactionManager transactionManager (DruidDataSource dataSource){
  6. LOGGER.info("【transactionManager 初始化...】");
  7. DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
  8. transactionManager.setDataSource(dataSource);
  9. return transactionManager;
  10. }
  11. /**
  12. * 创建事物手动管理模板
  13. */
  14. @Bean(name = "transactionTemplate")
  15. public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager)
  16. LOGGER.info("【transactionTemplate 初始化...】");
  17. TransactionTemplate transactionTemplate = new TransactionTemplate() ;
  18. transactionTemplate.setTransactionManager(transactionManager);
  19. return transactionTemplate;
  20. }

3、封装转账接口

接口方法

  1. public interface AccountService {
  2. /**
  3. * 汇款
  4. */
  5. void out (String outer , Integer money);
  6. /**
  7. * 收款
  8. */
  9. void in (String inner , Integer money);
  10. }

接口实现

  1. @Service
  2. public class AccountServiceImpl implements AccountService {
  3. @Resource
  4. private JdbcTemplate jdbcTemplate ;
  5. public void out(String outer, Integer money) {
  6. String sql = "update account set money = money - ? where username = ?";
  7. jdbcTemplate.update(sql, money,outer);
  8. }
  9. public void in(String inner, Integer money) {
  10. String sql = "update account set money = money + ? where username = ?";
  11. jdbcTemplate.update(sql, money,inner);
  12. }
  13. }

4、封装三个测试接口

测试接口

  1. public interface TradeService {
  2. /**
  3. * 转账交易:没有事务管理
  4. */
  5. void trade1(String outer ,String inner ,Integer money);
  6. /**
  7. * 转账交易:手动管理事务
  8. */
  9. void trade2(String outer ,String inner ,Integer money);
  10. /**
  11. * 转账交易:注解管理事务
  12. */
  13. void trade3(String outer ,String inner ,Integer money);
  14. }

接口实现

  1. @Service
  2. public class TradeServiceImpl implements TradeService {
  3. @Resource
  4. private AccountService accountService ;
  5. @Resource
  6. private TransactionTemplate transactionTemplate ;
  7. @Override
  8. public void trade1(String outer, String inner, Integer money) {
  9. accountService.out(outer, money);
  10. // 抛出异常
  11. int i = 1/0;
  12. accountService.in(inner, money);
  13. }
  14. @Override
  15. public void trade2(String outer, String inner, Integer money) {
  16. transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  17. public void doInTransactionWithoutResult(TransactionStatus arg0) {
  18. accountService.out(outer, money);
  19. // 抛出异常
  20. int i = 1/0;
  21. accountService.in(inner, money);
  22. }
  23. });
  24. }
  25. @Transactional(value="transactionManager",propagation= Propagation.REQUIRED)
  26. @Override
  27. public void trade3(String outer, String inner, Integer money) {
  28. accountService.out(outer, money);
  29. // 抛出异常
  30. int i = 1/0;
  31. accountService.in(inner, money);
  32. }
  33. }

5、编写测试类

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringBootTest(classes = TransactionApplication.class)
  3. public class TradeTest {
  4. @Resource
  5. private TradeService tradeService ;
  6. /**
  7. * 没有事务管理
  8. * jack 减少了1000块钱,但是rose得到1000块钱
  9. * 1 jack 9000
  10. * 2 rose 10000
  11. */
  12. @Test
  13. public void testTrade1 (){
  14. tradeService.trade1("jack", "rose", 1000);
  15. }
  16. /**
  17. * 手动管理事务
  18. * 1 jack 10000
  19. * 2 rose 10000
  20. */
  21. @Test
  22. public void testTrade2 (){
  23. tradeService.trade2("jack", "rose", 1000);
  24. }
  25. /**
  26. * 注解管理事务
  27. * 1 jack 10000
  28. * 2 rose 10000
  29. */
  30. @Test
  31. public void testTrade3 (){
  32. tradeService.trade3("jack", "rose", 1000);
  33. }
  34. }

四、源代码地址

  1. GitHub·地址
  2. https://github.com/cicadasmile/spring-boot-base
  3. GitEE·地址
  4. https://gitee.com/cicadasmile/spring-boot-base

SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作的更多相关文章

  1. (六)SpringBoot2.0基础篇- Redis整合(JedisCluster集群连接)

    一.环境 Redis:4.0.9 SpringBoot:2.0.1 Redis安装:Linux(Redhat)安装Redis 二.SpringBoot整合Redis 1.项目基本搭建: 我们基于(五) ...

  2. 4-9 基于Spring JDBC的事务管理(续)

    10. 基于Spring JDBC的事务管理(续) 当需要方法是事务性的,可以使用@Transactional注解,此注解可以添加在: 接口 会使得此接口的实现类的所有实现方法都是事务性的 接口中的抽 ...

  3. 【Spring实战】—— 16 基于JDBC持久化的事务管理

    前面讲解了基于JDBC驱动的Spring的持久化管理,本篇开始则着重介绍下与事务相关的操作. 通过本文你可以了解到: 1 Spring 事务管理的机制 2 基于JDBC持久化的事务管理 Spring的 ...

  4. 谈谈分布式事务之二:基于DTC的分布式事务管理模型[下篇]

    [续上篇] 当基于LTM或者KTM的事务提升到基于DTC的分布式事务后,DTC成为了本机所有事务型资源管理器的管理者:此外,当一个事务型操作超出了本机的范 围,出现了跨机器的调用后,本机的DTC需要于 ...

  5. SpringBoot2.0 基础案例(14):基于Yml配置方式,实现文件上传逻辑

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.文件上传 文件上传是项目开发中一个很常用的功能,常见的如头像上 ...

  6. SpringBoot2.0 基础案例(13):基于Cache注解模式,管理Redis缓存

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.Cache缓存简介 从Spring3开始定义Cache和Cac ...

  7. SpringBoot2.0基础案例(01):环境搭建和RestFul风格接口

    一.SpringBoot 框架的特点 1.SpringBoot2.0 特点 1)SpringBoot继承了Spring优秀的基因,上手难度小 2)简化配置,提供各种默认配置来简化项目配置 3)内嵌式容 ...

  8. SpringBoot2.0 基础案例(15):配置MongoDB数据库,实现增删改查逻辑

    本文源码:GitHub·点这里 || GitEE·点这里 一.NoSQL简介 1.NoSQL 概念 NoSQL( Not Only SQL ),意即"不仅仅是SQL".对不同于传统 ...

  9. SpringBoot2.0 基础案例(10):整合Mybatis框架,集成分页助手插件

    一.Mybatis框架 1.mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获 ...

随机推荐

  1. HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化

    题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  2. Spring Boot2.0之多数据源事务管理

    结合前面做的小项目,如果我把test01 test02下面的 service 都加了 事务的注解 这样启动时候会报错! 事务管理器里面不能有两个事务!!!! 这时候需要用  @Transactiona ...

  3. js正则表达式(2)

    找到以某个字符串开头的字符串 var myReg=/^(abc)/gim; 如果不加m,那么只找一行,而加了m可以找到每行中以该字符串开头的匹配文本. 如: abcsfsdfasd7890hklfah ...

  4. the art of seo(chapter eleven)

    Tracking Results and Measuring Success goal -> driver ***Why Measuring Success Is Essential to th ...

  5. Linux下查看端口占用情况

    用启动服务的账号登录,然后运行命令: lsof -i:<端口号> 也可使用命令: netstat -apn|grep <端口号> 找到进程号以后,再使用以下命令查看详细信息: ...

  6. Ubuntu更改启动内存

    参考:https://superuser.com/questions/152921/how-to-boot-with-mem-1024m-argument-using-grub-ubuntu-10-0 ...

  7. python基础-正则1

    什么是正则表达式? 正则表达式是一种小型的\高度专业化的变成语言,主要用于字符串处理 正则表达式是一种通用语言,在python中通过re模块实现,import re 工具:在线正则表达式测试 http ...

  8. Posix线程编程指南(2)

    这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第2篇将向您讲述线程的创建与取消. 一.概念及作用在单线程程序中,我们经常要用到"全 ...

  9. JDK中主要的包介绍

  10. Android Studio的技巧

    1.快速添加add unimplements methods:  右键generate 2.快速添加try-catch:左边就有一个小电灯,然后可以选. 3.格式化OPTION + CMD + L ( ...