Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you use 'For update skip locked' in postgres without locking rows in all tables used in the query?

When you want to use postgres's SELECT FOR UPDATE SKIP LOCKED functionality to ensure that two different users reading from a table and claiming tasks do not get blocked by each other and also do not get tasks already being read by another user:

A join is being used in the query to retrieve tasks. We do not want any other table to have row-level locking except the table that contains the main info. Sample query below - Lock only the rows in the table -'task' in the below query

SELECT v.someid , v.info,  v.parentinfo_id, v.stage  FROM task v, parentinfo pi  WHERE v.stage = 'READY_TASK' 
             AND v.parentinfo_id = pi.id 
             AND pi.important_info_number = ( 
             SELECT MAX(important_info_number) FROM parentinfo )
              ORDER BY v.id limit 200 for update skip locked;

Now if user A is retrieving some 200 rows of this table, user B should be able to retrieve another set of 200 rows.

EDIT: As per the comment below, the query will be changed to :

SELECT v.someid , v.info,  v.parentinfo_id, v.stage  FROM task v, parentinfo pi  WHERE v.stage = 'READY_TASK' 
             AND v.parentinfo_id = pi.id 
             AND pi.important_info_number = ( 
             SELECT MAX(important_info_number) FROM parentinfo)  ORDER BY v.id limit 200 for update of v skip locked;

How best to place order by such that rows are ordered? While the order would get effected if multiple users invoke this command, still some order sanctity should be maintained of the rows that are being returned.

Also, does this also ensure that multiple threads invoking the same select query would be retrieving a different set of rows or is the locking only done for update commands?

like image 427
Righto Avatar asked Jul 16 '17 18:07

Righto


People also ask

Does UPDATE query locks the table Postgres?

Mostly what happens when you try to UPDATE is that Postgres will acquire a lock on the row that you want to change. If you have two update statements running at the same time on the same row, then the second must wait for the first to process.

What is for UPDATE skip locked?

The SKIP LOCKED clause improves the scalability of applications that attempt to concurrently update the same set of rows in a table. It eliminates wait time for TX locks. Consistency and isolation are preserved.

Can we use with Nolock in PostgreSQL?

In SQLServer, you can use syntax "(nolock)" to ensure the query doesn't lock the table or isn't blocked by other queries locking the same table.

How do I stop a table locking in Postgres?

1: Never add a column with a default value Adding a column takes a very aggressive lock on the table, which blocks read and write. If you add a column with a default, PostgreSQL will rewrite the whole table to fill in the default for every row, which can take hours on large tables.


1 Answers

Just experimented with this a little bit - multiple select queries will end up retrieving different set of rows. Also, order by ensures the order of the final result obtained.

like image 188
Righto Avatar answered Sep 26 '22 15:09

Righto