目录

  • 事务的基本特征
  • 隔离级别
  • 传播行为
  • @Transcation

事务的基本特征(ACID)

Atomic(原子性)

  事务中包含的操作被看作一个整体的业务单元,这个业务单元中的操作要么全部成功,要么全部失败,不会出现部分失败和部分成功的场景

Consistency(一致性)

  事务在完成时,必须使所有的数据都保持一直状态,在数据库中所有的修改都基于事务,保证了数据的完整性

Isolation(隔离性)

  多个应用程序线程同时访问统一数据,这样数据库同样的数据就会在各个不同的事务中被访问,这样会产生丢失更新,为了压制丢失更新的产生,数据库定义了隔离级别的概念,通过它的选择,可以在不同程度上压制丢失更新的产生。因为互联网的应用常常面对高并发的场景,所以隔离性是需要掌握的重点内容

Durability(持久性)

  事务结束后,所有的数据都会固化到一个地方,如保存磁盘当中,即时断电重启后也可以提供应用程序访问


  为了压制丢失更新,数据库提出了隔离级别,在不同程度上压制更新

  也许会有一个疑问,都全部消除丢失更新不就好了吗,为什么只是在不同的程度.上压制丢失更新呢?

  其实这个问题是从两个角度去看的,一个是数据的一致性,另一个是性能。数据库现有的技术完全可以避免丢失更新,但是这样做的代价,就是付出锁的代价,在互联网中,系统不单单要考虑数据的-致性,还要考虑系统的性能。试想,在互联网中使用过多的锁,--旦出现商品抢购这样的场景,必然会导致大量的线程被挂起和恢复,因为使用了锁之后,一个时刻只能有一个线程访问数据,这样整个系统就会十分缓慢,当系统被数千甚至数万用户同时访问时,过多的锁就会引发宕机,大部分用户线程被挂起,等待持有锁事务的完成,这样用户体验就会十分糟糕。因为用户等待的时间会十分漫长,一般而言,互联网系统响应超过5秒,就会让用户觉得很不友好,进而引发用户忠诚度下降的问题。所以选择隔离级别的时候,既需要考虑数据的一致性避免脏数据,又要考虑系统性能的问题。因此数据库的规范就提出了4种隔离级别来在不同的程度上压制丢失更新。

隔离级别

未提交读

  最低的隔离级别,含义是允许一个事务读取另外一个事务没有提交的数据。未提交读是一种危险的隔离级别,实际开发中应用不广

  • 优点:并发能力高。适合那些对数据一致性没有要求而追求高并发的场景
  • 缺点:出现脏读

读写提交

  指一个事务只能读取一个事务已经提交的数据,不能读取未提交的数据

  • 优点:克服脏读
  • 缺点:出现不可重复读

可重复读

  可重复读的目标是克服读写提交中出现的不可重复读的现象,因为在读写提交的时候,可能出现一些值的变化,影响当前事务的执行

  • 优点:克服不可重复读
  • 缺点:出现幻读

串行化

  数据库最高的隔离级别,它会要求所有的SQL都会按照顺序执行,这样就可以克服上诉隔离级别出现的各种问题,所以它能完全保证数据的一致性


  追求更高的隔离级别,它能更好地保证数据的一致性,但是也要付出锁的代价。有了锁,就意味着性能的丢失,而且隔离级别越高,性能越是直线下降。

  所以在选择隔离级别时,要考虑的不单单是数据一致性问题,还要考虑系统的性能问题

  一般而言,选择隔离级别会以读写提交为主,它能防止脏读,而不能避免不可重复读和幻读,为了克服数据不一致性和性能问题,程序开发者还设计了乐观锁,甚至不再使用数据库而使用其他手段

  对于隔离级别,不同的数据库支持也是不一样的

  • Oracle只支持读写提交和串行化,默认隔离级别为读写提交
  • MySQL能支持4种,默认隔离级别为可重复读

传播行为

  在Spring中,当一个方法调用另外一个方法,可以让事务采取不同的策略工作,如新建事务或挂起当前事务

  在一个批量任务执行的过程中,调用多个交易时,如果有一些交易发生异常,只是回滚出现异常的交易,而不是里整个批量任务,这样就能够是的那些没有问题的交易可以吮吸完成,而有问题的交易则不做任何事情


@Transcation

  对于声明式事务,使用@Transaction进行标注,可标注在类活着方法上,当它标注在类上时,代表这个类所有公共(public)非静态的方法都将启用事务功能

  默认配置下 Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error。

  • 捕获RuntimeException
  • 捕获Error
  • 并不捕获Checked Exception

有了@Transcation,Spring就会知道从哪启动事务,约定流程:

当上下文开始调用被@Transcation标注的类或者方法时,Spring就会产生AOP的功能。请注意事务的底层需要启动AOP功能,这就是Spring事务的底层实现

如有一个保存用户的方法,加入 @Transactional 注解,使用默认配置,抛出异常之后,事务会自动回滚,数据不会插入到数据库。

@RestController
public class HouseController {@Autowiredprivate HouseRepository houseRepository;@GetMapping("/test1")public String test1(){houseRepository.save(new House("house1", "100平方米"));houseRepository.save(new House("house2", "100平方米"));houseRepository.save(new House("house3", "100平方米"));houseRepository.save(new House("house444444444", "100平方米"));houseRepository.save(new House("house5", "100平方米"));return "success";}@GetMapping("/test2")@Transactionalpublic String test2(){houseRepository.save(new House("house6", "100平方米"));houseRepository.save(new House("house7", "100平方米"));houseRepository.save(new House("house8", "100平方米"));houseRepository.save(new House("house999999999", "100平方米"));houseRepository.save(new House("house10", "100平方米"));return "success";}
}

test1方法没有加入事务,test2方法加入了事务注解。

  test1:当输入http://localhost:8888/test1

  

数据库中插入了三条数据

因为第四条数据太长,所以插入失败,导致第五条正常数据插入失败,这并不是我们想要的,要么全成功,要么全失败

  test2:输入http://localhost:8888/test2

数据库中数据不变依然是三条数据,插入失败,所以全部回滚


本文借鉴:《深入浅出Spring Boot 2.x》书中有更详细的例子

返回顶部

转载于:https://www.cnblogs.com/echola/p/10999052.html

SpringBoot声明式事务相关推荐

  1. SpringBoot第七篇:springboot开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...

  2. 企业 SpringBoot 教程 (七)springboot开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...

  3. java版b2b2c社交电商spring cloud分布式微服务(七)springboot开启声明式事务

    java b2b2c 电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经 ...

  4. mybatis plus 事务管理器_SpringBoot第七篇:springboot开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...

  5. springboot开启声明式事务

    springboot开启声明式事务 转载http://blog.csdn.net/forezp/article/details/70833629 springboot开启事务很简单,只需要一个注解@T ...

  6. java B2B2C springmvc mybatis多租户电子商城系统 (七)springboot开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...

  7. Spring 声明式事务应该怎么学?

    1.引言 Spring 的声明式事务极大地方便了日常的事务相关代码编写,它的设计如此巧妙,以至于在使用中几乎感觉不到它的存在,只需要优雅地加一个 @Transactional 注解,一切就都顺理成章地 ...

  8. Spring声明式事务原理

    本文我们将通过一个简单的例子回顾Spring声明式事务的使用,并通过源码解读内部实现原理,最后通过列举一些常见事务不生效的场景来加深对Spring事务原理的理解. 1. 案例 新建SpringBoot ...

  9. 声明式事务(Transactional)的工作原理

    声明式事务(Transactional)的工作原理 1. 前置条件(pre-condition) 2. Transaction自动配置(TransactionAutoConfiguration) 2. ...

最新文章

  1. 第四代自动泊车从APA到AVP技术
  2. 《强化学习周刊》第32期:上海交大华为 | 可解释强化学习研究综述
  3. 安卓setclicklistener函数没有_金主脚本按键精灵安卓按键初体验—乱斗西游2自动签到...
  4. express+mongodb+vue实现增删改查-全栈之路2.0
  5. php中用户验证的方式,在php中进行用户身份验证的最佳方式是什么?
  6. 女朋友想进高校当老师,其实中学老师更适合他
  7. 启智社区亮相2020全球智博会,千万奖金悬赏优秀开发者
  8. 2017.6.4 入门组 NO.4——猜数
  9. WPF介绍和一些基础操作
  10. homework5_ZhankunLuo
  11. activemq下载安装(windows版)与实例创建,JMS模型介绍
  12. Letv超级电视再出发,这次拿什么讲故事?
  13. ch340是什么芯片
  14. vid在c语言中的作用,——PVID的作用及和VID的区别
  15. 高数 | 精通中值定理 解题套路汇总
  16. 如何删除双系统中的ubuntu
  17. 职业学校计算机和机电哪个好,职业学校都有什么专业10大热门专业
  18. 嵌入式linux界面开发,基于嵌入式Linux平台实现GUI系统的设计方案
  19. 【C++基础知识】常成员函数,常引用
  20. sqlmap tamper mysql_sqlmap tamper的使用

热门文章

  1. CPP_封装_继承_多态
  2. 灵动标签调用友情链接
  3. 考研编程练习----排名
  4. android模拟器安装及优化(集锦)
  5. 利用 Docker 搭建单机的 Cloudera CDH 以及使用实践
  6. 记录关于vs2008 和vs2015 的报错问题
  7. Linux下安全审计工具 lynis 使用说明
  8. Lync Server 2013无法共享PPT故障排错处理
  9. Troubleshooting(三):网络
  10. linux 用户创建、管理、权限分配