MySQL UPDATE 锁会因为连续的 SHARE 锁而饿死吗?
Can MySQL UPDATE locks starve due to continuous SHARE locks?
我有 2 个不同的事务,其中一个对 SELECT
语句使用读锁 (FOR SHARE
),另一个使用写锁 (FOR UPDATE
)。
假设他们正在尝试获取同一行上的锁。这是我试图了解发生了什么的场景。
假设我有连续不断的使用读锁的请求流,偶尔我需要获取写锁。
这些锁是使用 FIFO 策略来避免饥饿还是其他一些策略,例如读锁只要它可以获取锁就会获取,而写锁会等待所有的读取耗尽(即使是新的读取)例)。
我怀疑第二次可能会发生,但我不是 100% 确定。
我正在调查一个问题,但找不到关于此的良好文档。
如果你缺少文档,你可以尝试一个实验:
Window 1:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tablename for share;
+---------------------+
| ldt |
+---------------------+
| 1969-12-31 16:00:00 |
+---------------------+
1 row in set (0.00 sec)
Window 2:
mysql> update tablename set ldt=now();
(hangs, waiting for lock)
Window 3:
mysql> select * from tablename for share;
(hangs, also waiting for lock)
这表示 X-lock 请求正在阻止后续 S-lock 请求。
50 秒过去,然后:
Window 2:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
然后立即:
Window 3:
mysql> select * from tablename for share;
+---------------------+
| ldt |
+---------------------+
| 1969-12-31 16:00:00 |
+---------------------+
1 row in set (41.14 sec)
window中的select 3 在window中等待更新时被阻塞 2.当更新超时时,然后[=44中的select =] 3 人能够继续。
我有 2 个不同的事务,其中一个对 SELECT
语句使用读锁 (FOR SHARE
),另一个使用写锁 (FOR UPDATE
)。
假设他们正在尝试获取同一行上的锁。这是我试图了解发生了什么的场景。
假设我有连续不断的使用读锁的请求流,偶尔我需要获取写锁。
这些锁是使用 FIFO 策略来避免饥饿还是其他一些策略,例如读锁只要它可以获取锁就会获取,而写锁会等待所有的读取耗尽(即使是新的读取)例)。
我怀疑第二次可能会发生,但我不是 100% 确定。
我正在调查一个问题,但找不到关于此的良好文档。
如果你缺少文档,你可以尝试一个实验:
Window 1:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tablename for share;
+---------------------+
| ldt |
+---------------------+
| 1969-12-31 16:00:00 |
+---------------------+
1 row in set (0.00 sec)
Window 2:
mysql> update tablename set ldt=now();
(hangs, waiting for lock)
Window 3:
mysql> select * from tablename for share;
(hangs, also waiting for lock)
这表示 X-lock 请求正在阻止后续 S-lock 请求。
50 秒过去,然后:
Window 2:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
然后立即:
Window 3:
mysql> select * from tablename for share;
+---------------------+
| ldt |
+---------------------+
| 1969-12-31 16:00:00 |
+---------------------+
1 row in set (41.14 sec)
window中的select 3 在window中等待更新时被阻塞 2.当更新超时时,然后[=44中的select =] 3 人能够继续。