1.事务的四大特性
事务具有4个基本特征,分别是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Duration),简称ACID
① 原子性
事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,只允许出现两种状态之一,要么都成功,要么都失败
任何一项操作都会导致整个事务的失败,同时其它已经被执行的操作都将被撤销并回滚,只有所有的操作全部成功,整个事务才算是成功完成
② 一致性(Consistency)
事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行之前和执行之后,数据库都必须处以一致性状态。
比如:如果从A账户转账到B账户,不可能因为A账户扣了钱,而B账户没有加钱
③ 隔离性
事务的隔离性是指在并发环境中,并发的事务是互相隔离的,一个事务的执行不能被其它事务干扰。也就是说,不同的事务并发操作相同的数据时,每个事务都有各自完整的数据空间。
一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务是不能互相干扰的
④ 持久性(Duration)
事务的持久性是指事务一旦提交后,数据库中的数据必须被永久的保存下来。即使服务器系统崩溃或服务器宕机等故障。只要数据库重新启动,那么一定能够将其恢复到事务成功结束后的状态
2、 事务的隔离级别
a) 出现的问题
i. 脏读:一个事务读到另一个事务尚未提交的数据
ii. 不可重复读:一个事务在读取某些数据后的某个时间,在此读取以前读过的数据,却发现其读出的数据已经发生了改变或某些记录已经被删除了
iii. 幻读:一个事务按照相同的检索条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据
b) 数据库事务的4种隔离级别:由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable
i. Read uncommitted 读未提交
- 就是一个事务可以读取另一个未提交事务的数据(脏读)
ii. Read committed 读提交
- 就是一个事务要等另一个事务提交后才能读取数据(解决脏读),但是存在不可重复读的问题,比如一个事务存在两次读取,中间存在其他事务的修改,导致读取数据不一致。
iii. Repeatable read 重复读
- 重复读,就是在开始读取数据(事务开启)时,不再允许修改操作(解决了不可重复读的问题),但是解决不了新增数据的问题(幻读)
iv. Serializable 序列化
- 直接把所有序列串行执行,效率特别低,解决幻读的问题
v. 值得一提的是:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。
3、 事务的传播级别
a) 事务的传播都是相对于父方法而言的,不涉及子方法。比如A嵌套B,只存在B对于A的事务传播
b) spring事务的传播类型
i. 死活不要事务的
- PROPAGATION_NEVER,没有就非事务执行,有就抛出异常
- PROPAGATION_NOT_SUPPORTED,没有就非事务执行,有就直接挂起,然后非事务执行
ii. 可有可无的
- PROPAGATION_SUPPORTS,有就用,没有就算了
iii. 必须有事务的
- PROPAGATION_REQUIRES_NEW,有没有都新建事务,如果原来有,就将原来的挂起,两个事务互不影响
- PROPAGATION_REQUIRED(默认),如果没有,就新建一个事务,如果有,就加入当前事务
- PROPAGATION_NESTED:如果没有,就新建一个事务;如果有,就在当前事务中嵌套其他事务
- PROPAGATION_MANDATORY:如果没有,就抛出异常,如果有,就加入当前事务
iv. 名词解释
- PROPAGATION_NOT_SUPPORTED的挂起意思为,执行的线程只有一个,当代码执行到子方法时,父方法被挂起,子方法继续执行,子方法是非事务执行的,执行完成再把父方法唤醒从子方法之后的代码继续执行。当子方法出现异常,子方法不会回滚,只会像父方法抛出异常,如果父方法有处理异常,未出现其他错误,父方法也无需回滚。
- 加入父方法的事务(合并),意思为:无论父方法或者是子方法存在异常都会回滚,即使是父方法会处理子方法的异常父方法依旧会回滚
合并:要么执行,要么一起不执行。 - 嵌套的意思为:被嵌套事务不会影响外部事务,而外部事务会影响被嵌套的事务
v. 实例,A方法中(加try-catch)执行B方法
- A:required
B:never
抛异常 - A:无事务
B:never
正常执行 - A:required
B:PROPAGATION_REQUIRES_NEW
B出错B回滚,但是A正常执行。
A出错A回滚,但是B正常执行。 - A:required
B:PROPAGATION_REQUIRES
A出错A、B回滚
B出错A、B回滚 - A:required
B:nested
A出异常,B也会跟着回滚
B出异常,A无需回滚 - A:required
B:nested
A出异常,B也会跟着回滚
B出异常,A无需回滚