innodb 锁机制

参考文章:
http://www.cnblogs.com/zhoujinyi/p/3435982.html
https://www.cnblogs.com/janehoo/p/5603983.html
https://www.cnblogs.com/aipiaoborensheng/p/5767459.html

0 锁的分类以及加锁方式

  1. 行锁
    1. s锁,share lock共享锁
    2. x锁,排他锁
  2. 表锁
    1. 意向共享锁 IS
    2. 意向排他锁 IX
  3. 加锁方式
    1. select * from tb_name lock in share mode;
    2. select * from tb_name for update;

1 行锁

1 在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁

mysql> show create table tab_no_index;
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table        | Create Table
                                                                   |
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tab_no_index | CREATE TABLE `tab_no_index` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+--------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

---`session 1`
mysql> select * from tab_no_index where id = 1 for update;     
+------+------+                                                
| id   | name |                                                
+------+------+                                                
|    1 | 1    |                                                
+------+------+                                                
1 row in set (0.00 sec) 

--- `session 2`

mysql> select * from tab_no_index for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction                                      

mysql> select * from tab_no_index;
+------+------+
| id   | name |
+------+------+
|    1 | 1    |
|    2 | 2    |
|    3 | 3    |
|    4 | 4    |
+------+------+
4 rows in set (0.00 sec)                                                               

2 由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以虽然是访问不同行的记录,但是如果是使用相同的索引键,是会出现锁冲突的。应用设计的时候要注意这一点。

---session 1 加排它锁
mysql> select * from tab_has_index where id =1 for update;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
+----+------+
1 row in set (0.00 sec)

--- session 2
mysql> select * from tab_has_index where id =1;              
+----+------+                                                
| id | name |                                                
+----+------+                                                
|  1 | 1    |                                                
+----+------+                                                
1 row in set (0.00 sec)                                      

-- 会话2 加排它锁                                                             
mysql> select * from tab_has_index where id =1 for update;   
^C^C -- query aborted                                        
ERROR 1317 (70100): Query execution was interrupted          
mysql> select * from tab_has_index where id =2 for update;   
+----+------+                                                
| id | name |                                                
+----+------+                                                
|  2 | 2    |                                                
+----+------+                                                
1 row in set (0.00 sec)                                      

3 当表有多个索引的时候,不同的事务可以使用不同的索引锁定不同的行,另外,不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁

4 即便在条件中使用了索引字段,但是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的,如果MySQL认为全表扫描效率更高,比 如对一些很小的表,它就不会使用索引,这种情况下InnoDB将使用表锁,而不是行锁。因此,在分析锁冲突时,别忘了检查SQL的执行计划,以确认是否真 正使用了索引

2 间隙锁(gap lock)

3 next-key锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值