MySQL 中的四种事务隔离机制

总结

  • 读未提交(Read Uncommitted):这是最低的隔离级别,一个事务可以读取其他事务未提交的修改,可能导致脏读(dirty read)。
  • 读已提交(Read Committed):这个级别保证了一个事务只能读取其他事务已经提交的修改,避免了脏读,但可能出现不可重复读(non-repeatable read)。
  • 可重复读(Repeatable Read):这是MySQL InnoDB引擎的默认隔离级别。这个级别通过使用事务开始时的快照来保证一个事务多次查询结果相同,避免了不可重复读,但可能出现幻读(phantom read)。
  • 可串行化(Serializable):这是最高的隔离级别,它通过对所有涉及的数据加锁来保证一个事务不受其他事务影响,避免了幻读,但牺牲了并发性能。

举例

假设有两个事务T1和T2同时操作一个表users,表中有一条记录id=1,username=‘Alice’。

  • 读未提交:如果T1修改了username为’Bob’,但还没有提交,T2就可以读取到这个修改。这就是脏读,因为T1可能会回滚,导致数据不一致。
  • 读已提交:如果T1修改了username为’Bob’并提交了,T2第一次读取到的是’Bob’,但如果T1再次修改了username为’Charlie’并提交了,T2第二次读取到的就是’Charlie’。这就是不可重复读,因为同一个事务内多次查询结果不同。
  • 可重复读:如果T1修改了username为’Bob’并提交了,T2第一次和第二次都读取到的是’Alice’,因为它使用的是事务开始时的快照。但如果T1插入了一条新记录id=2,username=’David’并提交了,T2就可以看到这条新记录。这就是幻读,因为同一个事务内查询出现了新的数据。
  • 可串行化:如果T1修改或插入任何数据,并且加锁了相应的行或表,在它提交之前,T2无法对这些数据进行任何操作。这样可以保证数据的完整性和一致性。

最后

幻读是指在一个事务中,两次执行相同的查询,但返回的结果集不同。这可能会导致数据的不一致性和逻辑错误。

举个例子,假设T2想要统计users表中有多少条记录,它第一次查询得到的结果是1(只有id=1的记录)。但如果T1在此期间插入了一条新记录id=2并提交了,T2第二次查询得到的结果就是2(多了id=2的记录)。这就是幻读,因为T2期望两次查询结果相同,但实际上出现了新的数据

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!