Re: pg_advisory_lock() and row deadlocks

From: Eliot Gable <egable+pgsql-general(at)gmail(dot)com>
To: Chris Angelico <rosuav(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: pg_advisory_lock() and row deadlocks
Date: 2012-04-20 16:25:22
Message-ID: CAD-6L_WoZ06j9wKxQBpreUK1fhJMJF4rKaL+WxEOH0BSXhC=Ew@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Fri, Apr 20, 2012 at 11:46 AM, Chris Angelico <rosuav(at)gmail(dot)com> wrote:

>
> You have a Dining Philosophers Problem. Why can you not control the
> order in which they acquire their locks? That's one of the simplest
> solutions - for instance, all update locks are to be acquired in
> alphabetical order of table name, then in primary key order within the
> table. Yes, select locks last until the end of the transaction, but
> are you really sure you can safely release the locks earlier? By
> releasing those advisory locks, you're allowing the transactions to
> deadlock, I think. Attempting a manual interleave of these:
>
> Transaction 1 grabs pg_advisory_lock(1)
> Transaction 2 grabs pg_advisory_lock(2)
> Transaction 1 runs a statement that updates multiple rows on Table A
> Transaction 2 runs a statement that deletes multiple rows on Table B
> Transaction 1 releases pg_advisory_lock(1)
> Transaction 2 releases pg_advisory_lock(2)
> Transaction 1 continues processing other stuff
> Transaction 2 continues processing other stuff
>
> At this point, Transaction 1 retains the locks on rows of Table A, and
> Transaction 2 retains locks on B.
>
> Transaction 1 grabs pg_advisory_lock(2)
> Transaction 2 grabs pg_advisory_lock(1)
> Transaction 1 runs a statement that updates multiple rows on Table B
> -- Lock --
> Transaction 2 runs a statement that deletes multiple rows on Table A
> -- Deadlock --
>
> Your advisory locks aren't actually doing anything for you here.
>
> ChrisA
>

How do you control the order in which cascading deletes occur across tables
and the order in which they fire the triggers which do the locking?

Within a single function or even within a couple of functions, I can
control the order. But they are called from within triggers on tables on
cascading delete or update operations. How do I control that? Some
functions only need to lock certain tables while other functions need a
large set of the tables locked. All the functions and triggers lock tables
in alphabetical order, and I have rolled the locking out to the furthest
level based on what sub-functions call. However, transaction 1 might call
function1() first and then function2() and transaction 2 might call
function2() first and then function1() and those functions might grab locks
on Table A and B independently, but then when transaction 1 or 2 calls
function3(), it needs to work with both tables, and then they deadlock.
Function1() or function2() might be called in a transaction without ever
calling function3() in that transaction, so it doesn't make sense to lock
all the tables in function1() and function2() that function3() also locks.

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Vincenzo Romano 2012-04-20 16:26:56 Re: How to drop a temporary view?
Previous Message Tom Lane 2012-04-20 16:07:06 Re: How to drop a temporary view?