说在最前面
- 使用可重复读隔离级别
准备
建表
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`val` int(11) DEFAULT NULL,
`updated_at` timestamp(3) NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
PRIMARY KEY (`id`) USING BTREE,
KEY `b` (`val`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `test-env`.`t`(`id`, `val`, `updated_at`)
VALUES (1, 100, '2021-01-09 17:51:00.243');
实验
这里通过updated_at
字段作为版本号
说明:
另个事务同时操作同一行数据,其中一个事务会阻塞,获取到行锁的事务提交后,会修改版本号(也就是表中的updated_at
字段)。此时,另一个事务获取到锁之后,因为where
条件中带版本号,所有更新会失败(这里显示:Affected Row: 0
)。
补充
事务1:SQL
set TRANSACTION ISOLATION LEVEL REPEATABLE READ;
begin;
update t set val = 101 where id=1 and updated_at='2021-01-09 17:51:00.243';
COMMIT;
事务2:SQL
set TRANSACTION ISOLATION LEVEL REPEATABLE READ;
begin;
update t set val = 102 where id=1 and updated_at='2021-01-09 17:51:00.243';
COMMIT;