mysql中的意向锁IS,IX

看mysql官方文档:InnoDB事务模型和锁定

知识储备:

  1、官方文档上说mysql是支持非锁定读的;这个功能是这样实现的,如果事务a 要对行的数据进行更新的话,那么事务a要得到行的x锁,并把这一行

     之前的样子记录在undo log里面,这样一来如果a 事务rollback 了就可以通过undo log 来恢复到之前的样子;说白了非锁定的一致性读就是读的

     行的undo log 中的内容,所以这货根本就不用上锁。

  2、在mysql中事务与锁的关系:

     1、事务开始之后申请锁。

     2、得到锁之后才进行相关的操作,事务提交或回滚之后才会去释放申请到的锁。

  3、如果想要select 语句也加上s锁可以在select 后面加上lock in share mode 子句。

  4、mysql支持意向锁、意向锁是在表级别上的;

  

  5、innodb 对锁的分配方式:

     1、innodb 的锁是需要用到的时候才会去分配,并是一次性要把事务要用到的锁分配完成后才去执行事务。

     2、对锁的申请请求是放在一个队列当中的,请申请的先得到。

 

例子:一个lock in share mode 引起的死锁问题:

  1、准备环境:

create database tempdb;
use tempdb;
create table t(x int);
insert into t(x) values(1);

  2、事务一执行如下语句:

复制代码
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t where x=1 lock in share mode;
+------+
| x    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)
复制代码

  3、事务二执行如下语句:

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> delete from t where x=1;

  4、接着事务一又执行如下语句:

mysql> delete from t where x=1;

  5、最后mysql 监控到死锁

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

 

原因分析:

  1、事务一先是得到了x=1 这一行上的s 锁;

  2、事务二要去申请x=1    这一行上的x锁,由于事务一已经得到了s锁,所以它要等待事务一释放s锁。

  3、事务一又想去申请x=1  这一行上的x锁,由于事务二的申请在事务一的前面发起,所以它要等待事务二完成后才能得到。

  

  由以上分析可知,事务一,事务二产生了相互等待;进而死锁产生。 

 

因此,InnoDB对客户端A产生一个错误,并且释放它的锁定。在那一点
上,客户端B的锁定请求可以被许可,并且客户端B从表中删除行。

posted @ 2019-08-15 14:32  上台阶  阅读(2790)  评论(0编辑  收藏  举报