Note that there are some explanatory texts on larger screens.

plurals
  1. PODeadlock involving foreign key constraint
    primarykey
    data
    text
    <p>I would like to understand better a mechanism of locking in postgres.</p> <p>Let's say that tree can have apples (via foreign key on apple table). It seems that when selecting a tree for update lock is obtained on an apple. However, the operation is not blocked even if someone else already holds a lock on this apple.</p> <p>Why is it so?</p> <p>p.s. Please don't suggest to remove "select for update".</p> <h1>Scenario</h1> <pre><code>Transaction 1 Transaction 2 BEGIN . update apple; . . BEGIN . select tree for update; . update apple; . --halts because of the other transaction locking an apple update apple; . -- deadlock . COMMIT --transaction succeeds </code></pre> <h1>Code</h1> <p>If you want to try it in your postgres - here is a code you can copy/paste.</p> <p>I have a following db schema</p> <pre><code>CREATE TABLE trees ( id integer primary key ); create table apples ( id integer primary key, tree_id integer references trees(id) ); </code></pre> <p>and very simple data</p> <pre><code>insert into trees values(1); insert into apples values(1,1); </code></pre> <p>There are two simple transactions. One is updating apples, the second is locking a tree and updating an apple.</p> <pre><code>BEGIN; UPDATE apples SET id = id WHERE id = 1; -- run second transaction in paralell UPDATE apples SET id = id WHERE id = 1; COMMIT; BEGIN; SELECT id FROM trees WHERE id = 1 FOR UPDATE; UPDATE apples SET id = id WHERE id = 1; COMMIT; </code></pre> <p>When I run them - deadlock occurs on the second update of first transaction.</p> <pre><code>ERROR: deadlock detected DETAIL: Process 81122 waits for ShareLock on transaction 227154; blocked by process 81100. Process 81100 waits for ShareLock on transaction 227153; blocked by process 81122. CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."trees" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR SHARE OF x" </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload