1.事务ACID特性
MYSQL事务的实现是通过ACID特性来保证的,ACID是指原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
- 原子性:指事务是一个不可分割的工作单元,事务中的所有操作要么全部完成,要么全部不完成。
- 一致性:指事务执行前后,数据库的状态应该保持一致。
- 隔离性:指多个事务之间相互隔离,每个事务的执行都不会影响其他事务。
- 持久性:指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。
2.脏读、幻读和不可重复读
在理解事务隔离级别之前,需要理解脏读、幻读和不可重复读概念。
2.1.脏读(dirty read)
指一个事务读取了另一个事务尚未提交的数据。比如,事务 A 更新了一个记录,但是并没有提交,此时事务 B 读取了这个记录,此时如果事务 A 回滚,那么事务 B 读取的数据就是“脏数据”,因为这个数据根本不存在。
2.2.幻读(phantom read)
指在一个事务中多次查询同一个范围的数据,但是其他事务插入了新数据,导致第二次查询时返回了不同的结果。比如,事务 A 查询一个范围的数据,此时事务 B 插入了一些新数据,那么在事务 A 再次查询这个范围的数据时,结果集中就会出现“幻象”,即之前未出现过的数据。
2.3.不可重复读(non-repeatable read)
指在一个事务中,多次读取同一个数据,但是在读取过程中其他事务进行了修改,导致读取到的结果不一致。比如,事务 A 读取了一个记录,此时事务 B 更新了这个记录并提交,那么事务 A 再次读取这个记录时,发现和之前读取的结果不同,这就是“不可重复读”。
2.4.幻读和不可重复读的区别
不可重复读和幻读的区别在于,不可重复读是由其他事务修改了已有数据导致的,而幻读是由其他事务插入或删除新数据导致的。此外,不可重复读一般发生在读取同一行数据的情况下,而幻读则是发生在读取一个范围内的数据时。因此,不可重复读一般与UPDATE语句有关,而幻读则一般与INSERT或DELETE语句有关。
3.事务隔离级别
MYSQL事务隔离级别有下面4种:
- 读未提交(Read uncommitted):允许脏读,一个事务可以读取到另一个事务未提交的数据,可能会导致数据不一致的情况。
- 读已提交(Read committed):一个事务只能读取到另一个事务已经提交的数据,解决了脏读的问题,但可能会导致不可重复读和幻读问题。
- 可重复读(Repeatable read):保证同一事务多次读取同一数据的结果是一致的,解决了不可重复读的问题,但可能会导致幻读问题。
- 串行化(Serializable):所有的事务依次执行,最高的隔离级别,保证了事务之间的完全隔离,但性能较差。
MYSQL默认隔离级别是可重复读(Repeatable read)。
不同的隔离级别特性如下:
- 读未提交(Read uncommitted):最低的隔离级别,性能最好,但容易出现脏读的问题。
- 读已提交(Read committed):解决了脏读的问题,但可能会导致不可重复读和幻读问题。
- 可重复读(Repeatable read):保证同一事务多次读取同一数据的结果是一致的,解决了不可重复读的问题,但可能会导致幻读问题。
- 串行化(Serializable):保证了事务之间的完全隔离,但性能较差,一般不建议使用。