目录
- 一、4大特性(ACID)
- 二、隔离级别
- 三、传播机制
一、4大特性(ACID)
- 原子性(A):在一个事务中,要么全部成功,要么全部失败。
- 一致性(C):事务完成时,所有数据都保持一致的状态,例如:在银行转账,A向B转1000,A扣1000,B加1000要一起成功或失败。
- 隔离性(I):多个事务的执行是互不干扰的。
- 持久性(D):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
参考: 事务的4大特性、事务隔离级别、事务传播行为
二、隔离级别
- 读未提交(脏读)
- 其他事务还没提交,但是当前事务已经读到了被修改的数据
- 由于可以读到其他未提交事务提交的数据,所以叫做脏读。
- 读已提交(不可重复读)
- 当前事务还没提交,但是可以读到其他已经提交的事务修改的数据
- 由于可以读到其他事务已提交的数据,所以两次查询可能会产生不一样的结果。
- 可重复读(幻读)
- 如果事务A和事务B都在进行中,事务A在数据库中插入了一条主键为1的一条数据,并且结束事务;然后事务B查询数据库中不存在主键为1的数据,所以再次执行插入操作,发现逐渐冲突,这种现象类似于幻读
- 由于事务只要不结束,多次查询的结果都是一样的,这就是可以重复读。
- 串行化:事务排队执行,每次执行一个。
参考: 事务的4大特性、事务隔离级别、事务传播行为
三、传播机制
- required(默认):如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
- requires_new:创建一个新事务,如果存在当前事务,则挂起该事务。
- supports:当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
- mandatory:当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。
- not_supported:始终以非事务方式执行,如果当前存在事务,则挂起当前事务
- never:不使用事务,如果当前事务存在,则抛出异常
- nested:如果当前事务存在,则在嵌套事务中执行,否则自己新建一个事务
- 和requires_new的区别:requires_new是新建一个事务并且新开启的这个事务与原有事务无关,而nested是当前存在事务时(我们把当前事务称之为父事务)会开启一个嵌套事务(称之为一个子事务)。在nested情况下父事务回滚时,子事务也会回滚,而在requires_new情况下,原有事务回滚,不会影响新开启的事务。
- 和required的区别:required情况下,调用方存在事务时,则被调用方和调用方使用同一事务,那么被调用方出现异常时,由于共用一个事务,所以无论调用方是否catch其异常,事务都会回滚;而在nested情况下,被调用方发生异常时,调用方可以catch其异常,这样只有子事务回滚,父事务不受影响。
参考: 带你读懂Spring 事务——事务的传播机制