In PostgreSQL, do multiple UPDATEs to different rows in the same table have a conflicting locks?

后端 未结 2 673
野趣味
野趣味 2021-01-20 08:07

I\'m wondering about an update I am making to a large table, and whether I need to worry about locks.

I have a table looking like this:

CREATE TABLE          


        
2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-20 08:36

    UPDATE locks the row, so you do not need to lock it first. If you try to UPDATE overlapping sets of rows simultaneously, the second UPDATE will wait for the first's transaction to commit or roll back.

    The big problem with your approach - other than the fact that UPDATE doesn't have a LIMIT clause - is that multiple workers will all try to grab the same rows. Here's what happens:

    • worker1: Filters the table to find 200 rows and locks them
    • worker1: starts updating rows
    • worker2: filters the table to find 200 rows
    • worker2: tries to start updating rows, but has selected the same rows as worker1 so it blocks on worker1's lock
    • worker1: Finishes updating rows
    • worker2: After lock release, re-checks the WHERE condition and finds out that none of the rows match anymore because worker1 has updated them. Updates zero rows.

    ... and repeat!

    You need to either:

    • Have a central queue handing out rows in a proper concurrency-safe way; or
    • Assign workers non-overlapping ranges of IDs to work on

    As for LIMIT - you could use WHERE id IN (SELECT t.id FROM thetable t LIMIT 200 ORDER BY id) - but you'd have the same problem with both workers choosing the same set of rows to update.

提交回复
热议问题