数据库事务与锁(四)——实战

本文主要围绕主键(同行、不同行)加锁、普通列加锁、索引(普通索引、唯一索引)列加锁几种情况进行展开说明。

新建数据库tbook,id列为主键,name列为唯一索引,price列为普通索引,author列为普通列:

CREATE TABLE `tbook` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `author` varchar(25) DEFAULT '',
  `price` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_name` (`name`) USING BTREE,
  KEY `index_price` (`price`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

主键加锁

1) 同行

不同事务

(同行)

SX
S允许不允许
X不允许不允许

演示:事务一:

 

事务二:

分析:对比事务一与事务二,发现给同一行主键加X锁,会出错。可以通过查看相关的表INNODB_LOCKS, INNODB_LOCK_WAITS, INNODB_TRX查看事务与锁的具体情况。其他情况(S+S,S+X,X+S)可自行验证。

2) 不同行

不同事务

(不同行)

SX
S允许允许
X允许允许

演示:事务一:

 

事务二:

分析:对比事务一与事务二,发现给不同行的逐渐加X锁,不影响。其他情况(S+S,S+X,X+S)可自行验证。

总结:主键加锁不会引起全表加锁,只会针对特定行。

普通列加锁

不同事务

(同行或不同行)

SX
S允许不允许
X不允许不允许

演示:事务一:

 

事务二:

分析:事务一对普通列author(此时Id为1)加X锁,事务二对Id=2行加X锁,报错。查看INNODB_TRX表,查看trx_rows_locked字段,可以看出对普通列加锁,会导致给表中的每一行进行加锁。

总结:普通列加锁,会引起全表扫描, 导致全表数据被锁。

索引列加锁

1) 唯一索引

演示:事务一:

 

事务二:

分析:事务一对唯一索引name列加X锁,事务二对其他name列或主键列加X锁,不影响,对同一行的主键加锁时会报错。

总结:唯一索引列加锁,只加锁一条,不会导致全表数据被锁。

2) 普通索引

演示:事务一:

 

事务二:

分析:事务一对普通索引price列加X锁,查看表INNODB_TRX的字段trx_rows_locked=3,事务二再插入数据,发现有些可以插入成功,有些却失败,原因就在于间隙锁和NEXT-KEY锁的存在。由于间隙锁和NEXT-KEY锁的存在,普通索引列会分为几个区间范围,(负无穷,10),(10,20),(20,30),(30,44),(44,90),(90,正无穷)。因为对price=10加锁,则位于10的前后区间,即(负无穷,10),(10,20)均受到影响。

总结:普通索引加锁,由于间隙锁或NEXT-KEY锁的存在,会影响多行数据被锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值