什么是事务
逻辑上的一组操作,要么全都执行,要么全都不执行。
事务的特性(ACID)
- 原子性(A):一组操作语句要么全都执行,要么全都不执行,不存在执行一部分的情况。
- 一致性(C):事务只能从一个一致性状态转变为另一个一致性状态。也就是事务执行前后,数据是一致的。
- 隔离性(I):多个事务之间是互相独立的,不会相互干扰。
- 持久性(D):事务对数据的修改是永久的,即使是数据库宕机或崩溃也不会改变。
👀:只有原子性,隔离性,持久性实现的前提下,一致性才能得到保证
在事务的并发执行过程中,往往会产生以下几个问题
- 脏读:一个事务(A)读取到另一个事务(B)修改但未提交的数据。此时,我们称A读取到的数据是“脏数据”。使用“脏数据”操作是不正确的
- 不可重复读:事务A第一次读取到某一数据值为1,之后事务B修改此数据为2,事务A再次读取此数据时值变为了2。即,同一事务多次读取到的数据不一致的情况成为不可重复读
- 幻读:与不可重复读类似,指事务A在两次读取数据之间,事务B增加或删除了一些数据。导致事务A两个读取到的数据行数不一致的情况。
- 丢失修改:事务A和事务B对某一数据C进行修改,事务A把C的值改为1,然后事务B把C的值改为2,此时事务A修改的数据被覆盖。此过程称为丢失修改。
❓:不可重复读和幻读的区别
不可重复读在于对数据的修改,表现在某个数据上。而幻读则是对数据的增加或删除,表现在数据行的增加或减少。
事务的隔离级别
- READ-UNCOMMITTED(读取未提交):可以读取到尚未提交的数据。会有脏读,幻读,不可重复读的问题
- READ-COMMITTED(读取已提交):可以读取到已经提交的数据。会有幻读,不可重复读的问题,解决了脏读的问题
- REPEATABLE-READ(可重复读):事务多次读取到的结果是一致的(本事务自己修改的数据除外),会有幻读的问题,解决脏读,不可重复读的问题
- SERIALIZABLE(可串行化):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
👀 MySQL的InnoDB存储引擎默认的是可以重复读
参考JavaGuide