【 TiDB 使用环境】测试
【 TiDB 版本】v6.5.0
【复现路径】
在TiDB创建如下表并插入数据
CREATE DATABASE test;
CREATE TABLE test.student (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
INSERT INTO student (name) VALUES ('John');
INSERT INTO student (name) VALUES ('Alice');
INSERT INTO student (name) VALUES ('Bob');
INSERT INTO student (name) VALUES ('Emma');
随后开启两个会话,按照如下顺序测试
Process1 | Process2 |
---|---|
use test; | |
start transaction; | |
use test; | |
start transaction; | |
select name from student s where id=2 for update; | |
select name from student s where id=2 for update; | |
update student set name = ‘Eric’ where id = 1; | |
commit; | |
select * from student where id = 1; | |
commit; |
【遇到的问题:问题现象及影响】
Process2的select * from student where id = 1;
读取到的仍然是John而非Eric
而同样的操作在MySQL上执行时,Process2的select * from student where id = 1;
读取到的却是Eric
该问题是因为MySQL的延迟加载导致的
begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作InnoDB表的语句(第一个快照读语句),事务才真正启动。如果你想要马上启动一个事务,可以使用start transaction with consistent snapshot 这个命令。
但这样无疑会导致TiDB和MySQL在某些场景下结果不同
想问一下能否调整为和MySQL一致,另外这是否会导致某些原本适配MySQL的代码出现问题?我个人理解是有可能的,因为之前MySQL是可以把锁后更新的值同步给下一个锁的获取者的,但在TiDB上着就不行了