Pra*_* M 28 mysql locking transactions
根据MySql文档,MySql支持多粒度锁定(MGL).
打开终端1:
//连接到mysql
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select id, status from tracking_number limit 5 for update;
+----+--------+
| id | status |
+----+--------+
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 0 |
| 5 | 0 |
+----+--------+
5 rows in set (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
把它打开并打开终端2:
//连接到mysql
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select id, status from tracking_number limit 5 for update;
<!-- Hangs here. and after some time it says-->
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Run Code Online (Sandbox Code Playgroud)
虽然有很多行需要检索,但T2会等到t1完成.
左端子1原样.现在在端子-2中:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
<!-- case 2.1 -->
mysql> select id, status from tracking_number where id=1;
+----+--------+
| id | status |
+----+--------+
| 1 | 0 |
+----+--------+
1 row in set (0.00 sec)
mysql> select id, status from tracking_number where id=2;
+----+--------+
| id | status |
+----+--------+
| 2 | 0 |
+----+--------+
1 row in set (0.00 sec)
<!-- case 2.2 -->
mysql> select * from tracking_number where id=2 for update;
<!-- Hangs here. and after some time -->
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Run Code Online (Sandbox Code Playgroud)
但是为什么在情况1中,T2等待T1锁定的同一组行?
这是否意味着无限制的选择查询(即使使用limint参数.我也尝试过不同的范围)阻止整个表?
开通终端和交易:
mysql> update tracking_number set status=4 where status=0 limit 5;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
Run Code Online (Sandbox Code Playgroud)
把它留在那里并打开另一个终端和交易:
mysql> update tracking_number set status=5 where status=0 limit 5;
Run Code Online (Sandbox Code Playgroud)
在我提交(或回滚)T1之前,T2没有成功.
rav*_*nur 24
让我来看看你的案例并解释这些锁是如何工作的:
1例
T1想要更新测试表中的某些行.此事务将IX锁定放在所有表上,并将X锁定放在前5行上.
T2想要更新测试表中的某些行.此事务将IX(因为IX与IX兼容)锁定在所有表上并尝试前5行但由于X与X不兼容而无法执行此操作
所以我们没事.
2.1案例
T1想要更新测试表中的某些行.此事务将IX锁定放在所有表上,并将X锁定放在前5行.
T2想要从测试表中选择一些行.并且它没有放置任何锁(因为InnoDB提供非锁定读取)
2.1案例
T1想要更新测试表中的某些行.此事务将IX锁定放在所有表上,并将X锁定放在前5行.
T2想要从测试表中更新(选择更新)某些行.将IS放在整个表上并尝试对该行进行S锁定并失败,因为X和S不兼容.
还要始终注意隔离级别:不同级别会导致不同的机制来释放/获取锁定
希望能帮助到你