提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
本文主要讲声明式事务(也就是事务注解)
一、Spring的事务
Spring 事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring 是 无法提供事务功能的。真正的数据库层的事务提交和回滚是通过 binlog 或者 redo log 实 现的。
- 本地事务
- 全局事务
spring 事务实现主要有两种方法
- 编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法
- 声明式,利用注解 Transactional 或者 aop 配置
1.Spring事务传播行为
事务传播是spirng对事务的一个强大支持,采用了动态代理的方法,对事务的一种加强操作,让开启了事务的方法和方法之间的调用更加灵活,例如:A,B两个方法都开启了事务,若A方法调用了B方法,若采用的是spring的事务管理,就产生了事务方法的相互调用问题,默认情况下,B方法的事务会被A方法覆盖,若此时B方法的事务要独立于A方法外的话,就可以采用事务传播来解决。
① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前 存在事务,就加入该事务,该设置是最常用的设置。
② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务, 如果当前不存在事务,就以非事务执行。
③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事 务,如果当前不存在事务,就抛出异常。
④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建 新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务, 就把当前事务挂起
⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前 没有事务,则按 REQUIRED 属性执行。
2.隔离级别
设置隔离界别:用@Transactional 注解声明式事务的事务管理中来设置 isolation 属性的隔离级别 在配置文件中设置事务tx:method元素
ISOLATION 隔离的意思
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别, 使用数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个 事务未提交的数据。
③ ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才 能被另一事务读取,而且能看到该事务对已有记录的更新。解决脏读问题
④ ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才 能被另一事务读取,但是不能看到该事务对已有记录的更新。行锁
⑤ ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据 库所做的更新。表锁
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插 入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查 询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。 发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据, 同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了
原理
二、Spring事务失效的几种原因
-
spring的事务注解 @Transactional只能放在public修饰的方法上才起作用 ,如果放在其他非public(private,protected)方法上,虽然不报错,但是事务不起作用
-
如果采用spring+spring mvc,则context:component-scan重复扫描问题可能会引起事务失败。
-
如使用mysql且引擎是MyISAM,则事务会不起作用,原因是MyISAM不支持事务,可以改成InnoDB引擎
-
@Transactional 注解开启配置,必须放到listener里加载,如果放到DispatcherServlet的配置里,事务也是不起作用的。
-
Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。
-
在业务代码中如果抛出RuntimeException异常,事务回滚;但是抛出Exception,事务默认是不回滚Exception异常的;
-
如果在加有事务的方法内,使用了try…catch…语句块对异常进行了捕获,而catch语句块没有throw new RuntimeExecption异常,事务也不会回滚
-
在类A里面有方法a 和方法b, 然后方法b上面用 @Transactional加了方法级别的事务,在方法a里面 调用了方法b, 方法b里面的事务不会生效。原因是在同一个类之中,方法互相调用,切面无效 ,而不仅仅是事务。这里事务之所以无效,是因为spring的事务是通过aop实现的。
三、数据库的事务
1、事务的四大特性ACID性质
并非任意的对数据库的操作序列都是数据库事务。数据库事务拥有以下四个特性,习惯上被称之为ACID特性。
(1)原子性(Atomicity):整个事务中的所有操作,要么全部完成,要么全部不完成,不会停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback) 到事务开始前的状态,就像这个事务从来没有执行过一样。 即,事务不可分割、不可约简。
(2)一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。 这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
(3)隔离性(Lsolation):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能, 事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化 请 求,使得在同一时间仅有一个请求用于同一数据。
(4)持久性(Durability):在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,即便系统故障也不会丢失。
数据完整性
(英语:data integrity)是信息安全的三个基本要点之一; 在传输、存储信息或数据的过程中,确保信息或数据不被未授权的篡改或在篡改后能够被迅速发现。在信息安全领域使用过程中,常常和保密性混淆。通常使用数字签名、散列函数等手段保证数据完整性。
触发器
(英语:trigger)是在数据库中,在执行对资料有异动的动作时,先行拦截并处理的一种数据库对象,它大部分会设在资料表中,作为强制执行特定动作的程序,因此又称为数据操纵语言(DML)触发器。
级联回滚
(cascading rollback)是指数据库的一个事务的失败引起多个事务随之失败,都要各自回滚。
四、事务怎么做
- 待办事务
参考文章
作者 :维基百科
作者:一路奔跑1314:Spring事务失效的几种原因