【问题标题】:LOCK IN SHARE MODE and FOR UPDATE vs nothing in MariaDB锁定共享模式和更新,而不是 MariaDB 中的任何内容
【发布时间】:2020-06-06 15:27:55
【问题描述】:

This question 比较 SELECT...LOCK IN SHARE MODESELECT...FOR UPDATE。但是,这两个与事务中的 SELECT 有何不同?数据库是 MariaDB,但如果没有差异,MySQL 的答案也应该没问题。最重要的是,我需要在避免数据库死锁的背景下获得信息。

【问题讨论】:

    标签: mysql sql select transactions mariadb


    【解决方案1】:

    可以避免很多死锁;有些不能。没有一种技术可以防止所有死锁。

    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 很容易导致“竞争条件”,其中两个连接以不一致的方式作用于同一行。

    另一个注意事项:如果您以相同的顺序“锁定”相同的行,那么一个连接可能会停止,直到另一个连接释放。 (cf innodb_lock_wait_timeout,默认为 50 秒 [我认为时间过长])

    (我所有的讨论都应该适用于 MySQL 或 MariaDB 中所有版本的 InnoDB/XtraDB。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-22
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多