MVCC一致性读
并发控制的方法
并发的任务对同一个临界资源进行操作,如果不采取措施,可能导致不一致,故必须进行并发控制(Concurrency Control)。 技术上,通过并发控制保证数据一致性的常见手段有:
- 锁(Locking)
- 数据多版本(Multi Versioning)
锁
MVCC
数据多版本是一种能够进一步提高并发的方法,它的核心原理是:
- 写任务发生时,将数据克隆一份,以版本号区分;
- 写任务操作新克隆的数据,直至提交;
- 并发读任务可以继续读取旧版本的数据,不至于阻塞;
提高并发的演进思路,就在如此:
- 普通锁,本质是串行执行
- 读写锁,可以实现读读并发
- 数据多版本,可以实现读写并发
一致非锁定读(Consistent Nonlocking Reads)
一致性是指,当前事务事务只能读取事务开始时的数据快照,包含两部分
- 事务开始前就已经存在的数据
- 事务自身插入或者修改的数据
事务开始时间:
- 在可重复读(Repeatable read)的隔离级别下,同一个事务内一致性读,读取的是事务内第一次发起读请求时构建的数据快照。
需要注意的是:一致性读仅应用于SELECT语句,对DML语句不适用。如果一行数据被另一个事物修改过,当前事务也修改了这一行数据时, 另一个事务的变更对当前事务可见。
eg:
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)。