Spring数据库事务管理
自主学习并掌握什么是事务,了解事务的隔离级别和传播行为。
什么是事务?
指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。
事务其实是数据库操作的最小单元,一个事务包含一系列操作,这些操作要么都执行成功,要么都执行失败。Transaction 也就是所谓的事务了,通俗理解就是一件事情。
多条DML要么同时成功,要么同时失败
基本操作:
-
开始事务
-
如果发生了错误,进行回滚
-
如果没有发生错误,则提交事务
事务的四个过程:
开启事务(start transaction)
执行核心业务代码
提交事务(如果核心业务处理过程中没有出现异常)(commit transaction)
回滚事务(如果核心业务处理……出现异常)(rollback transaction)
事务的四大特性
原子性(Atomicity):事务不可再分,要么都执行,要么都不执行。
一致性(Consistency):事务执行前后,数据的完整性保持一致,即修改前后数据总量是一样的大概。
隔离性(Isolation):一个事务执行过程中,不会受到其他事务干扰。
持久性(Durability):事务一旦结束,对数据库的影响是永久的。数据持久化到数据库中。
在并行程序中可能会出现的问题:
- Dirty Read(脏读):事务 A 读取了事务 B 未提交的数据,并在这个基础上又做了其他操作
- Unrepeatable Read(不可重复读):事务 A 读取了事务 B 已提交的更改数据
- Phantom Read(幻读):事务 A 读取了事务 B 已提交的新增数据
- 脏读:当 A事务 读取 B事务 未提交的数据后,B事务 回滚,导致 A事务 读取到的数据为脏数据。
- 不可重复读:A事务 读取第一次读取数据后,B事务 对该数据进行了修改并提交,A事务 再去读取数据时,前后数据结果不一致。
- 幻读:A事务 读取第一次读取数据后,B事务 又插入或删除了新的数据并提交,A事务 再去读取数据时,前后结果不一致。
Spring事务的五个隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted 读未提交 | 会 | 会 | 会 |
read committed 读提交 | 不会 | 会 | 会 |
repeatable read 可重复读 | 不会 | 不会 | 会 |
serializable 串行化 | 不会 | 不会 | 不会 |
ISOLATION_DEFAULT:使用数据库默认的事务隔离级别。
ISOLATION_READ_UNCOMMITTED:事务最低的隔离级别,允许一个事务可以读取另一个事务未提交的数据。 会产生脏读、不可重复读和幻读。
ISOLATION_READ_COMMITTED: 保证一个事务只能读取另一个事务修改并提交后的数据,不能读取未提交的数据。防止脏读。
ISOLATION_REPEATABLE_READ:保证一个事务不能更新另一个事务修改但尚未提交的数据。可以避免脏读和不可重复读。
ISOLATION_SERIALIZABLE:序列化执行所有事务。都避免了,但是效率极低。
传播行为是什么?
在service类中有a()方法和b()方法,a()方法上有事务,b()方法上也有事务,当a()方法执行过程中调用b()方法,事务是如何传递的?合并到一个事务里?还是开启一个新的事务?这就是事务传播行为。
Spring事务的七个传播行为
PROPAGATION_REQUIRED
RROPAGATION_REQUIRES_NEW
PROPAGATION_NESTED
PROPAGATION_SUPPORTS
PROPAGATION_NOT_SUPPORTED
PROPAGATION_NEVER
PROPAGATION_MANDATORY
在同一个事务中:
PROPAGION_REQUIRED(默认):支持当前事务,不存在则创建一个新的事务。
PROPAGION_SUPPORTS:支持当前事务,不存在就以非事务方式运行。
PROPAGION_MANDATORY:支持当前事务,如果不存在,抛出异常。
不同事务中:
PROPAGIN_REQUIRES_NEW:当前存在事务则挂起,创建一个新事务。
PROPAGION_SUPPORTS:当前存在事务则挂起,以非事务方式运行。
PROPAGION_NEVER:当前存在事务抛出异常,非事务方式运行。
PROPAGION_NESTED:当前存在事务则嵌套事务执行。
Spring 给我们带来了事务传播行为,这确实是一个非常强大而又实用的功能。除此以外,也提供了一些小的附加功能,比如:
事务超时(Transaction Timeout):为了解决事务时间太长,消耗太多的资源,所以故意给事务设置一个最大时常,如果超过了,就回滚事务。
只读事务(Readonly Transaction):为了忽略那些不需要事务的方法,比如读取数据,这样可以有效地提高一些性能。
可在 @Transactional 注解中设置:事务隔离级别、事务传播行为、事务超时时间、是否只读事务。
Spring事务管理
1、事务添加J2EE三层结构里面Service层(业务逻辑层)
2、在Spring进行事务管理操作两种方式:
①、编程式事务管理(自己写流程)
②、声明式事务管理:基于注解方式、基于xml配置文件方式
3、声明式事务管理:
基于注解方式
基于xml配置文件方式
4、在Spring进行声明式事务管理,底层使用AOP原理
5、Spring事务管理API:
PlatformTransactionManager
创建事务管理器
-
开启事务注解
-
在service类上面(或者service类里面方法上面)添加事务注解:@Transactional,这个注解添加到类上面,也可以添加方法上面
-
如果把这个注解添加类上面,这个类里面所有的方法都添加事务
-
如果把这个注解添加方法上面