How to set timeout for "SELECT FOR UPDATE" in transaction in PostgreSQL?

2k Views Asked by At

I have product table with id, name and stock as shown below.

product table:

id name stock
1 Apple 10
2 Orange 20

Then, after T1 runs SELECT FOR UPDATE, T2 needs to wait for T1 to commit for a long time to run SELECT FOR UPDATE as shown below because SELECT FOR UPDATE doesn't have timeout by default:

Flow Transaction 1 (T1) Transaction 2 (T2) Explanation
Step 1 BEGIN; T1 starts.
Step 2 BEGIN; T2 starts.
Step 3 SELECT stock FROM product WHERE id = 2 FOR UPDATE;

20
With "SELECT FOR UPDATE", T1 reads 20.
Step 4 SELECT stock FROM product WHERE id = 2 FOR UPDATE; T2 needs to wait for T1 to commit to read stock with "SELECT FOR UPDATE".
Step 5 Waiting... ...
Step 6 Waiting... ...
Step ... Waiting... ...
Step ... Waiting... ...
Step ... Waiting... ...
Step 98 COMMIT; Waiting... T1 commits.
Step 99 SELECT stock FROM product WHERE id = 2 FOR UPDATE;

20
Now with "SELECT FOR UPDATE", T2 reads 20
Step 100 COMMIT; T2 commits.

Now, I want T2 to rollback 3 seconds after T2 waits for T1 as shown below:

Flow Transaction 1 (T1) Transaction 2 (T2) Explanation
Step 1 BEGIN; T1 starts.
Step 2 BEGIN; T2 starts.
Step 3 SELECT stock FROM product WHERE id = 2 FOR UPDATE;

20
With "SELECT FOR UPDATE", T1 reads 20.
Step 4 SELECT stock FROM product WHERE id = 2 FOR UPDATE; T2 needs to wait for T1 to commit to read stock with "SELECT FOR UPDATE".
Step 5 Waiting... ...
Step 6 Waiting... ...
Step 7 ROLLBACK; T2 rollbacks 3 seconds after T2 waits for T1.
Step ...
Step ...
Step 98
Step 99
Step 100 COMMIT; T1 commits.

So, how can I set the timeout of 3 seconds for SELECT FOR UPDATE in transaction in PostgreSQL?

1

There are 1 best solutions below

0
On

Take a look at this answer: https://stackoverflow.com/a/20963803/8963723

BEGIN;
SET LOCAL lock_timeout = '3s';
SELECT ....;
COMMIT;