mysql RR级别各种锁表现演示
1.表结构
CREATE TABLE `transaction_test` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`a` int(10) DEFAULT NULL,
`b` int(10) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `idx_a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
陈述:范围查询加锁是加在索引上,等值查询是锁行,没有索引即锁表。
演示没有索引字段加锁,锁全表。
演示普通索引等值更新
1.等于存在的值,左开右闭,锁住(5,10]区间。
下图为补录,为证明确实是锁的区间,表结构和数据同上,库名和表名略有差异而已。
此时,更新不存在的值不受影响:
2.等于一个不存在的值,左开右开,锁住(5,10)区间,更新同样不存在的值不受影响。
演示等值唯一索引
CREATE TABLE `transaction_test` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`a` int(10) DEFAULT NULL,
`b` int(10) DEFAULT NULL,
`c` int(10) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_c` (`c`) USING BTREE,
KEY `idx_a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
1.等于唯一索引,行锁,只锁住一行,通过其他条件(比如id)更新该行数据同样会被阻塞。
通过主键id同样是锁行,根据其他条件更新该行数据会阻塞。
2.加锁在唯一索引上,但是值不存在,左开右开,锁住(5,10)间隙,更新同样不存在的值不受影响。
主键id上的加锁情况同上。
3.插入数据,当前行加锁:
演示普通索引范围搜索
1.锁住范围最大最小值的左开右闭间隙(5,10],但是,范围查询是锁索引,根据id可以更新a=10那条记录:
演示唯一索引范围搜索
1.锁住范围最大最小值的左开右闭间隙(5,10],同上,范围查询是锁索引,根据id可以更新c=10那条记录:
2.锁住(5,15]间隙,同上,范围查询是锁索引,根据id可以更新c=15那条记录:
演示唯一索引范围查询:
1.锁住范围最大最小值的左开右闭间隙(5,10],同上,范围查询是锁索引,根据id可以更新c=10那条记录
2.主键id范围查询,锁住id(5,9)区间,跟别的索引不一样的是,这里不能通过其他索引条件更新id=9的记录:
6.select lock in share mode,锁范围同上,只能加S锁,不能加X锁(如果先加S锁的事物,在后面加X锁时未有其他事物加S锁,则当前事物允许加X锁,后面的事物只能按已有X锁处理,即不能再加S锁了),当前读操作均为X锁(select for update,update,insert,delete)