MySQL Others--读写偏序问题

读偏序(Read Skew)

在已提交读(read committed)事务隔离级别下,事务T1先读取数据X,然后事务T2修改数据X和Y,然后事务T1再读取数据Y,事务T1读取到的X和Y不满足一致性约束。

在可重复读(Repeatable Read)事务隔离级别下,事务T1先读取数据X,然后事务T2修改数据X和Y,然后事务T1再读取数据Y,事务T1读取到的X和Y都是T2修改前的数据,满足一致性约束。

写偏序(Write Skew)

写偏序(Write Skew)也是一致性约束下的异常现象,即两个并行事务都基于自己读到的数据集去覆盖另一部分数据集,在串行化的情况下两个事务无论那种顺序执行,最终都会达到一致状态,但在快照(Snap)事务隔离级别下无法实现,即黑白球问题:

如下面场景:

## 初始化测试数据
CREATE TABLE tb1001(id INT PRIMARY KEY,c1 INT);
CREATE TABLE tb1002(id INT PRIMARY KEY,c1 INT);
INSERT INTO tb1001(id,c1)VALUES(1,11);
INSERT INTO tb1002(id,c1)VALUES(1,22);

在事务T1中执行:

BEGIN;
UPDATE tb1001 AS T1
INNER JOIN tb1002 AS T2
ON T1.id=T2.id
SET T1.c1=T2.c1;

在事务T2中执行:

BEGIN;
UPDATE tb1001 AS T1
INNER JOIN tb1002 AS T2
ON T1.id=T2.id
SET T2.c1=T1.c1;

在快照(Snap)事务隔离级别下,事务通过快照来读取数据,并不会对数据进行加锁保护,执行SQL不会被阻塞,由于两个事务修改的数据没有冲突,因此能够提交成功。

在MySQL的已提交读(read committed)事务隔离级别或可重复读(Repeatable Read)事务隔离级别时,MySQL会对更新的记录加X锁进行保护,对更新依赖的记录在读取时加S锁进行保护,因此当事务T1未提交前,事务T2被被阻塞,等待锁信息为:

mysql> select * from information_schema.INNODB_LOCKS \G
*************************** 1. row ***************************
    lock_id: 11916729688:830:3:2
lock_trx_id: 11916729688
  lock_mode: S
  lock_type: RECORD
 lock_table: `test`.`tb1001`
 lock_index: PRIMARY
 lock_space: 830
  lock_page: 3
   lock_rec: 2
  lock_data: 1
*************************** 2. row ***************************
    lock_id: 11916729687:830:3:2
lock_trx_id: 11916729687
  lock_mode: X
  lock_type: RECORD
 lock_table: `test`.`tb1001`
 lock_index: PRIMARY
 lock_space: 830
  lock_page: 3
   lock_rec: 2
  lock_data: 1
2 rows in set (0.00 sec)

参考资料

posted @ 2023-01-31 16:22  TeyGao  阅读(347)  评论(0编辑  收藏  举报