From: | Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com> |
---|---|
To: | HORDER Phil <Phil(dot)Horder(at)uk(dot)thalesgroup(dot)com> |
Cc: | pgsql-general <pgsql-general(at)postgresql(dot)org> |
Subject: | Re: Foreign Key locking / deadlock issue. |
Date: | 2018-03-20 14:04:11 |
Message-ID: | 8069590f-ca76-e5f8-fd28-2ba381c9fc82@aklaver.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
On 03/20/2018 06:55 AM, HORDER Phil wrote:
Please reply to list also.
Ccing list.
Still not certain what the PK is or what key value refers to?
> Well this is just sample SQL to demonstrate the problem.
> If each process executes lines of code alternately, a deadlock occurs.
>
> The commit would obviously be required by an application, but one transaction would be cancelled by the deadlock exception, and the demonstrator would rollback the other.
>
> Phil Horder
> Database Mechanic
> -----Original Message-----
> From: Adrian Klaver [mailto:adrian(dot)klaver(at)aklaver(dot)com]
> Sent: 20 March 2018 13:51
> To: HORDER Phil; pgsql-general(at)lists(dot)postgresql(dot)org
> Subject: Re: Foreign Key locking / deadlock issue.
>
> On 03/20/2018 04:46 AM, HORDER Phil wrote:
>> Hi,
>>
>> I'm trying to understand why I'm getting a deadlock issue, and how to
>> work around it.
>>
>> At base, I think the problem is:
>>
>> 1.Updates to a parent table are creating row level write locks,
>>
>> 2.updates to a child table set the foreign key value to the parent
>> table, which are then blocked.
>>
>> While investigating, I found the row locking documentation, which says
>> that I can request read locks that don't block.
>>
>> But my sample code still gets blocked.
>>
>> https://www.postgresql.org/docs/9.6/static/explicit-locking.html
>>
>> Can someone explain what I'm missing please?
>>
>> parent process
>>
>> -------------------
>>
>> start transaction;
>>
>> select * from pl where pl_id in (2,3) for no key update of pl; (1)
>>
>> update pl set m_number = '234' where pl_id = 2; (2)
>>
>> update pl set m_number = '345' where pl_id = 3; (3)
>>
>> child process
>>
>> -------------------
>>
>> start transaction;
>>
>> select pl_id from pl where pl_id in (2,3) for key share of pl; (4)
>>
>> update eln set pl_id = 3 where event_id = 303; (5)
>>
>> update eln set pl_id = 2 where event_id = 302; (6)
>
>
> I do not see a commit for either transaction.
>
>>
>> My Parent process inserts and updates on the PL table, but never
>> changes the key value.
>
> I am assuming when you say key value you are referring to PRIMARY KEY?
>
> What is the key(PK) column?
>
>>
>> My Child process inserts and updates on the ELN table, and can set the
>> FK reference value to the PL table.
>>
>> I can understand that the default lock on the PL update will block the
>> foreign key check from the ELN table.
>>
>> Why does this example still get blocked?
>>
>> Is there a way around this without dropping the foreign key?
>>
>> (And if so.. How can I get this to work in Spring Data / JPA?)
>>
>> Phil Horder
>>
>> Database Mechanic
>>
>> Thales
>>
>> Land and Air Systems
>>
>> Horizon House, Throop Road, Templecombe, Somerset, BA8 0DH, UK
>>
>
>
> --
> Adrian Klaver
> adrian(dot)klaver(at)aklaver(dot)com
>
--
Adrian Klaver
adrian(dot)klaver(at)aklaver(dot)com
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2018-03-20 14:27:57 | Re: You might be able to move the set-returning function into a LATERAL FROM item. |
Previous Message | Adrian Klaver | 2018-03-20 14:00:55 | Re: PostgreSQL 9.6 Temporary files |