做门户网站需要什么条件,产品销售网站模块如何设计,如果建立网站,做窗帘网站本文在锁概述的基础上#xff0c;通常实验举例#xff0c;详细地介绍了意向锁的原理。 锁范围 全局锁#xff08;global lock#xff09;表锁#xff08;table lock#xff09;行锁 (row lock) ROW LOCK的粒度LOCK_REC_NOG_GAP, record lock with out gap lockLOCK_GAP通常实验举例详细地介绍了意向锁的原理。 锁范围 全局锁global lock表锁table lock行锁 (row lock) ROW LOCK的粒度LOCK_REC_NOG_GAP, record lock with out gap lockLOCK_GAP gap lock LOCK_ORDINARY , next key lock record lock gap lock 锁等待与死锁锁等待 事务提交或等待超时死锁是一个死循环。死锁中必有锁等待。 表锁5.5以后在server层实现表锁innodb中有IS/IX表级锁以及自增锁auto-inc 读锁加读锁后只能对表读不能对表写允许多个会话同时读其他会话可以加共享读锁lock table table_name read 写锁lock table table_name write持有锁的会话可写可读其他会话访问表或请求加锁都会被阻塞直到锁释放 释放锁unlock tables;lock table 锁不能相互嵌套一个事务开始就意味着另外一个事务结束显式开启一个事务因为事务中不能支持表锁所以事务开始则表锁断开Kill或连接断开 innodb锁默认为行锁在索引上加锁来实现行锁如果没有索引那么升级为全表记录锁最终效果等同于表锁但表锁只需要在根节点上加锁而不是对所有记录加锁所以代价要小一些 锁类型共享锁排他锁/独占锁意向锁innodb特有加在表级别上的锁 共享锁与独占锁均用于事务当中随事务的结束而解除。 共享锁share lock又称读锁读取操作创建的锁。一旦上锁任何事务包括当前事务无法对其修改其他事务可以并发读取数据也可在对此数据再加共享锁语法SELECT ... LOCK IN SHARE MODE; 排他锁exclusive lock又称写锁如果事务对数据A加上排他锁后则其他事务不可并发读取数据也不能再对A加任何类型的锁。获得排他锁的事务既能读数据又能修改数据。语法SELECT ... FOR UPDATE这里的“其他事务不可并发读取数据”指的是不可以加共享锁即不可以以lock in share mode的方式读取数据比如 会话一 mysql select * from test for update;
----------------
| id | v1 | v2 |
----------------
| 1 | 1 | 0 |
| 2 | 3 | 1 |
| 3 | 4 | 2 |
| 5 | 5 | 3 |
| 7 | 7 | 4 |
| 10 | 9 | 5 |
----------------
6 rows in set (0.00 sec) 会话二 mysql select * from test lock in share mode;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 直接查询完全可以 mysql select * from test;
----------------
| id | v1 | v2 |
----------------
| 1 | 1 | 0 |
| 2 | 3 | 1 |
| 3 | 4 | 2 |
| 5 | 5 | 3 |
| 7 | 7 | 4 |
| 10 | 9 | 5 |
----------------
6 rows in set (0.00 sec) 这是因为直接查询走的是一致性快照读读的是MVCC版本控制下的快照不加锁换句话说排他锁排斥的“读”是指S锁下的读或者说是当前读 意向锁InnoDB的表级锁其设计目的主要是为了在一个事务中揭示下一步将要被请求的锁的类型。InnoDB中的两个表锁意向共享锁IS表示事务准备给数据行加入共享锁也就是说一个数据行加共享锁前必须先取得该表的IS锁意向排他锁IX类似上面表示事务准备给数据行加入排他锁说明事务在一个数据行加排他锁前必须先取得该表的IX锁。意向锁是InnoDB自动加的不需要用户干预。 意向锁是表级锁事务要获取表A某些行的S锁必须要获取表A的IS锁事务要获取表A某些行的X锁必须要获取表A的IX锁 会话一锁定了全表 会话二结果集为空时不加锁 意向锁的目的在于提高innodb性能会话一锁定的是全表那么会话二一看全表已被锁定则不再去看每行是否锁定会话二先判断表上有没有表锁如果没有表级锁则开始判断有没有行级锁 会话一不锁定全表的S锁 会话二立即执行不被锁v1上有索引 v1字段上有索引v2字段上没有索引有索引时优先按有索引的规则来当字段上没有索引时S锁X锁走意向锁的逻辑会话一 mysql begin;select * from test where v1 4 lock in share mode;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 5 | 5 | 3 |
| 7 | 7 | 4 |
| 10 | 9 | 5 |
----------------
3 rows in set (0.00 sec)mysql rollback;
Query OK, 0 rows affected (0.00 sec)mysql begin;select * from test where v2 4 lock in share mode;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 10 | 9 | 5 |
----------------
1 row in set (0.00 sec) 会话二 mysql begin;select * from test where v1 2 for update;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 1 | 1 | 0 |
----------------
1 row in set (0.00 sec)mysql rollback;
Query OK, 0 rows affected (0.00 sec)mysql
mysql
mysql begin;select * from test where v2 2 for update;
Query OK, 0 rows affected (0.00 sec)ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql 如果不是S锁而是快照读的话不会走意向锁的逻辑因为快照读不加锁不管是RC还是RR隔离级别 会话一 mysql begin;select * from test where v2 4;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 10 | 9 | 5 |
----------------
1 row in set (0.00 sec) 会话二立即执行没有锁等待 mysql begin;select * from test where v2 2 for update;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 1 | 1 | 0 |
| 2 | 3 | 1 |
----------------
2 rows in set (0.00 sec) 对于无索引的情况更新任何一条记录都会对该表加锁这时意向锁将非常有用但这个场景有个例外--“半一致性读” 半一致性读的条件5.7及以下版本时需要innodb_locks_unsafe_for_binlog 开启或事务隔离级别为RC语言类型为update8.0版本语言类型为update事务隔离级别为RCinnodb_locks_unsafe_for_binlog 参数被废弃。 8.0中半一致性读测试mysql set global transaction isolation level read committed;Query OK, 0 rows affected (0.00 sec) 会话一 mysql begin;select * from test where v2 4 for update;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 10 | 9 | 5 |
----------------
1 row in set (8.77 sec) 会话二显式开始一个事务被阻塞直接使用update语句不被阻塞注意v2字段上无索引 mysql begin;select * from test where v2 2 for update;
Query OK, 0 rows affected (0.00 sec)^C^C -- query aborted
ERROR 1317 (70100): Query execution was interruptedmysql select * from test;
----------------
| id | v1 | v2 |
----------------
| 1 | 1 | 0 |
| 2 | 3 | 1 |
| 3 | 4 | 2 |
| 5 | 5 | 3 |
| 7 | 7 | 4 |
| 10 | 9 | 5 |
----------------
6 rows in set (0.00 sec)mysql update test set v2 1 where v2 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 2 Changed: 1 Warnings: 0mysql exit 8.0的RR隔离级别mysql set global transaction isolation level repeatable read;Query OK, 0 rows affected (0.00 sec)会话一X锁测试 mysql begin;select * from test where v2 4 for update;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 10 | 9 | 5 |
----------------
1 row in set (0.00 sec) 会话二 mysql update test set v2 1 where v2 2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 8.0中半一致读的条件RC及以下隔离级别update语句 对于RR隔离级别无索引的情况下S锁X锁走意向锁的逻辑 会话一S锁测试 mysql begin;select * from test where v2 4 lock in share mode;
Query OK, 0 rows affected (0.00 sec)----------------
| id | v1 | v2 |
----------------
| 10 | 9 | 5 |
----------------
1 row in set (0.00 sec) 会话二 mysql update test set v2 1 where v2 2;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 所以意向锁的关键在于是否是S锁与X锁如果是RC隔离级别需要注意一下“半一致性读”S锁会先有全表上加ISX锁会先在全表上加IXIS与IX互斥IX与IX及IS互斥 对于经常使用的RR隔离级别对于无索引字段意向锁减少了后来锁判断行记录上是否有锁的时间 转载于:https://www.cnblogs.com/perfei/p/11367804.html