在共享模式下锁定,在mariadb中更新vs不更新

rsl1atfo  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(307)

这个问题比较 SELECT...LOCK IN SHARE MODE 以及 SELECT...FOR UPDATE . 然而,这两个有什么不同的裸 SELECT 在交易中?数据库是mariadb,但是如果没有差异,mysql的答案也可以。最重要的是,我需要避免数据库死锁的上下文中的信息。

jobtbby3

jobtbby31#

许多死锁可以避免;有些人不能。没有一种技术可以防止所有死锁。 FOR UPDATE 似乎比 LOCK IN SHARE MODE . (我很想听到有人反驳。)
通常的模式似乎是:

BEGIN;
SELECT ... FOR UPDATE;  -- use the columns fetched; lock the row(s)
-- Note:  the locked rows may or may not actually be UPDATEd later
-- Note:  FOR UDPATE prevents other connections from grabbing the same row(s)
UPDATE/DELETE/... -- those rows.
COMMIT;

但是。。。上面的任何内容都不能阻止经典的死锁场景:

BEGIN;   -- connection 1
SELECT row 123 FOR UPDATE;
SELECT row 234 FOR UPDATE;
...

BEGIN;   -- connection 1
SELECT row 234 FOR UPDATE;
SELECT row 123 FOR UPDATE;  -- Note: locking order was swapped
...

没有做某种形式的工作 SELECT ...LOCK/UPDATE 很容易导致“竞争条件”,即两个连接以不一致的方式作用于同一行。
另一个注意事项:如果您以相同的顺序“锁定”相同的行,那么一个连接可能会暂停,直到另一个释放(囊性纤维变性 innodb_lock_wait_timeout ,默认值为50秒(我认为时间过长)
(我的所有讨论都应适用于mysql或mariadb中的innodb/xtradb的所有版本。)

相关问题