mysql插入意向锁测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql插入意向锁测试相关的知识,希望对你有一定的参考价值。

参考技术A 1、表结构

    CREATE TABLE `reno` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(10) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8

2、表数据

    insert into reno select 5, 'aa';

  insert into reno select 7, 'bb';

  insert into reno select 9, 'cc';

  insert into reno select 18, 'dd';

  insert into reno select 23, 'ee';

  insert into reno select 30, 'ff';

  insert into reno select 40, 'gg';

  insert into reno select 45, 'hh';

  insert into reno select 99, 'ii';

3、两种尝试

    下面两种方案都会造成阻塞,我理解都是事务1获取到了间隙锁,事务2获取插入意向锁阻塞,但是“show engine INNODB status\G;”输出结果不一样,

第一种方案
    事务1 lock_mode X locks gap before rec 我理解是间隙锁
    事务2 lock_mode X locks gap before rec insert intention waiting 我理解是获取插入意向锁

第二种方案

    事务1  trx id 9821 lock_mode X 我理解是 Next key锁
    事务2 lock_mode X insert intention waiting 我理解是获取插入意向锁
我的疑问 为什么两个方案,事务1获取的锁,以及事务2获取的锁都是不一样的呢 

第一种方案 

MYSQL-GAP&插入意向锁 死锁记录

1、建表:

CREATE TABLE `test_dead_lock` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `user_id` bigint(20) unsigned NOT NULL COMMENT 用户id',
  `user_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名',
`type` int(10) DEFAULT '0' COMMENT '类型',
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_idx` (`user_id`,`user_name`),
  KEY `idx_name` (`user_name`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='测试死锁表';

mysql 5.7,事务隔离级别RR,会话自动提交事务关闭【set autocommit=off;】

2、数据准备

INSERT INTO `test_dead_lock` (`id`, `user_id`, `user_name`, `type`)
VALUES
	(1,1,'name22',0),
	(2,2,'name22',0),
	(3,3,'name3',0),
	(4,4,'name22',0),
	(9,8,'name8',0),
	(12,10,'name10',0),
	(41,10,'name100',0),
	(64,11,'name11A',0),
	(65,12,'name12A',0);

3、事务处理

事务1事务2备  注
start transaction;
start transaction;

delete from test_dead_lock

where user_id=5 ;

不存在数据,加间隙锁

delete from test_dead_lock

where user_id=6 ;

不存在数据,加间隙锁

insert ignore into test_dead_lock

(user_id,user_name)
values

(5,'name5A'),(5,'name5AA');

加插入意向锁,等待2事务间隙锁释放

insert ignore into test_dead_lock

(user_id,user_name)
values

(6,'name6A'),(6,'name6AA');

加插入意向锁,等待1事务间隙锁释放

死锁

rollback;rollback;

备注:也可以直接 delete 13,14,插入13,14数据来验证,间隙锁范围是正无穷。

4、死锁日志

show engine innodb status;

5、涉及知识点:

 (1)mysql 事务隔离级别

(2)mysql 锁

以上是关于mysql插入意向锁测试的主要内容,如果未能解决你的问题,请参考以下文章

什么是MySQL插入意向锁?

什么是MySQL插入意向锁?

什么是MySQL插入意向锁?

Mysql 死锁过程及案例详解之插入意向锁与自增锁备份锁日志锁Insert Intention Lock Auto-increment Lock Backup Lock Log Lock

MYSQL-GAP&插入意向锁 死锁记录

MYSQL-GAP&插入意向锁 死锁记录