文章目录
- 事务基础概念
- 隔离性与隔离机制的重要性
- 四种隔离级别
- 读未提交
- 读已提交
- 可重复读
- 串行化
- 隔离级别设置与查看
事务基础概念
事务是一组数据库操作,这些操作要么全部成功执行,要么全部不执行。在 MySQL 中,事务通常以START TRANSACTION开始,以COMMIT(提交)或ROLLBACK(回滚)结束。事务具有原子性、一致性、隔离性和持久性(ACID)特性。
隔离性与隔离机制的重要性
隔离性确保每个事务在执行时感觉不到其他并发事务的存在。如果没有适当的隔离机制,多个事务同时操作相同的数据可能会导致数据不一致的情况,如脏读、不可重复读和幻读。
四种隔离级别
读未提交
脏读:假设事务 A 正在更新表中的一条记录,将某个字段的值从 10 修改为 20,但尚未提交。此时事务 B 读取该记录,得到了更新后的值 20。接着事务 A 由于某种原因回滚了操作,数据恢复到原来的值 10。事务 B 读取到的就是 “脏” 数据,这种情况就是脏读。
性能影响:这是隔离性最弱的级别,它允许事务读取未提交的数据,因此并发性能相对较高。不过,由于可能出现脏读问题,在实际应用中很少使用这个级别,除非对数据的实时性要求极高且可以容忍数据不一致的情况。
读已提交
不可重复读:事务 A 开始,读取了某记录的值为 10。然后事务 B 更新了这条记录,将其值改为 20 并提交。当事务 A 再次读取该记录时,得到的值为 20。对于事务 A 来说,同一事务内两次读取同一条记录得到了不同的值,这就是不可重复读。
性能与应用场景:读已提交级别可以有效避免脏读问题,在大多数数据库应用中是比较常用的隔离级别。它在保证数据相对一致性的同时,提供了较好的并发性能,适用于对数据实时性有一定要求,但对同一事务内数据多次读取的一致性要求不是特别严格的场景,如一些在线交易系统中的查询操作。
可重复读
幻读:事务 A 根据某个条件查询记录,例如 “SELECT * FROM table WHERE condition = true”,此时没有符合条件的记录。然后事务 B 插入了一条符合该条件的记录并提交。当事务 A 再次执行相同的查询语句时,发现有了一条之前不存在的记录,这就是幻读。
InnoDB 引擎下的解决方式:在 InnoDB 存储引擎下,可重复读级别通过使用 Next - Key Locks(间隙锁和行锁的组合)来解决幻读问题。它保证在一个事务执行期间,按照相同的查询条件进行查询时,不会出现新插入的符合条件的记录影响结果。
性能与应用场景:可重复读是 MySQL 默认的事务隔离级别。它在保证同一事务内数据读取一致性方面表现出色,适用于对数据一致性要求较高的场景,如财务系统、库存管理系统等。虽然它会使用间隙锁等机制来防止幻读,一定程度上影响并发性能,但在很多实际应用中,这种性能损失是可以接受的。
串行化
原理与执行方式:在串行化隔离级别下,事务被严格地串行执行。就好像多个事务在排队依次执行一样,一个事务完成所有操作后,下一个事务才能开始。
性能与应用场景:这种隔离级别可以完全避免脏读、不可重复读和幻读问题,保证了数据的最高程度的一致性。但是它的并发性能最差,因为所有事务都不能并发执行。通常只在对数据一致性要求极高,并且并发操作很少的情况下使用,如银行系统中的核心账务处理部分。
隔离级别设置与查看
- 在 MySQL 中,可以使用SET TRANSACTION ISOLATION LEVEL语句来设置事务隔离级别。例如,SET TRANSACTION ISOLATION LEVEL READ COMMITTED;设置为读已提交级别。
- 可以通过SELECT @@tx_isolation;(在 MySQL 8.0 之前)或SELECT @@transaction_isolation;(MySQL 8.0 及之后)来查看当前的事务隔离级别。