mysql - Locking rows for select query?

后端 未结 2 1829
一整个雨季
一整个雨季 2020-12-21 08:14

I have a mysql table (table-A) that contains a list of unique product ids. The app which utilizes this table makes use of multiple threads, each of which selects a table row

相关标签:
2条回答
  • 2020-12-21 08:47

    try with "lock table" command, I used 2 windows to show you:

    jcho_1> lock table t1 write;
    Query OK, 0 rows affected (0.00 sec)
    
    jcho_2> select * from t1;
    

    jcho_2 stay waiting to release table to be able to read, when jcho_1 do this:

    jcho_1> unlock tables;
    Query OK, 0 rows affected (0.00 sec)
    

    jcho_2 is able with his query.

    jcho_2> select * from t1;
    +----------+-------------+--------------+---------------------+
    | actor_id | first_name  | last_name    | last_update         |
    +----------+-------------+--------------+---------------------+
    |      206 | a           | b            | 0000-00-00 00:00:00 |
    |       71 | ADAM        | GRANT        | 2006-02-15 04:34:33 |
    |      132 | ADAM        | HOPPER       | 2006-02-15 04:34:33 |
    ...
    |        0 | 0           | 0            | 0000-00-00 00:00:00 |
    +----------+-------------+--------------+---------------------+
    202 rows in set (1 min 27.67 sec)
    

    enter image description here

    enter image description here

    0 讨论(0)
  • 2020-12-21 09:01

    Native MySQL locking doesn't provide this functionality. You could use a column to perform your "locks".

    Assuming each thread had a unique ID, you could create a column named thread_owner, with default 0.

    One thread would grab a row like this:

    UPDATE mytable
    SET thread_owner = :my_threadID
    WHERE thread_owner = 0
    LIMIT 1
    

    Then select the row like this (it might return none, if there were no rows to be processed):

    SELECT *
    FROM mytable
    WHERE thread_owner = :my_threadID
    

    Then process it, and finally delete it.

    This solution would work on both MyISAM and InnoDB.

    However, for InnoDB, it might be slow because each UPDATE statement is trying to lock all rows where thread_owner = 0, and unless you're sure you're locking all rows in the same order each time, it could even cause a deadlock. So, you might try explicitly locking the whole table in your UPDATE statement:

    LOCK TABLES mytable WRITE;
    UPDATE mytable
    SET thread_owner = :my_threadID
    WHERE thread_owner = 0
    LIMIT 1;
    UNLOCK TABLES;
    

    That way, both MyISAM and InnoDB will work the same way.

    0 讨论(0)
提交回复
热议问题