Skip to content

MVCC一致性读

并发控制的方法

并发的任务对同一个临界资源进行操作,如果不采取措施,可能导致不一致,故必须进行并发控制(Concurrency Control)。 技术上,通过并发控制保证数据一致性的常见手段有:

  1. 锁(Locking)
  2. 数据多版本(Multi Versioning)

MVCC

数据多版本是一种能够进一步提高并发的方法,它的核心原理是:

  1. 写任务发生时,将数据克隆一份,以版本号区分;
  2. 写任务操作新克隆的数据,直至提交;
  3. 并发读任务可以继续读取旧版本的数据,不至于阻塞;

提高并发的演进思路,就在如此:

  • 普通锁,本质是串行执行
  • 读写锁,可以实现读读并发
  • 数据多版本,可以实现读写并发

一致非锁定读(Consistent Nonlocking Reads)

一致性是指,当前事务事务只能读取事务开始时的数据快照,包含两部分

  1. 事务开始前就已经存在的数据
  2. 事务自身插入或者修改的数据

事务开始时间:

  • 在可重复读(Repeatable read)的隔离级别下,同一个事务内一致性读,读取的是事务内第一次发起读请求时构建的数据快照。

需要注意的是:一致性读仅应用于SELECT语句,对DML语句不适用。如果一行数据被另一个事物修改过,当前事务也修改了这一行数据时, 另一个事务的变更对当前事务可见。

eg:

sql
SELECT COUNT(c1)
FROM t1
WHERE c1 = 'xyz';
-- Returns 0: no rows match.
DELETE
FROM t1
WHERE c1 = 'xyz';
-- Deletes several rows recently committed by other transaction.

SELECT COUNT(c2)
FROM t1
WHERE c2 = 'abc';
-- Returns 0: no rows match.
UPDATE t1
SET c2 = 'cba'
WHERE c2 = 'abc';
-- Affects 10 rows: another txn just committed 10 rows with 'abc' values.
SELECT COUNT(c2)
FROM t1
WHERE c2 = 'cba';
-- Returns 10: this txn can now see the rows it just updated.

读取最新数据

如果想读取最新数据,可以使用SELECT ... FOR UPDATE或者SELECT ... LOCK IN SHARE MODE语句,这样可以锁定行,防止其他事务修改数据。 或者设置事务隔离级别为 读已提交(Read committed)。

参考文档