On Fri, Apr 20, 2012 at 11:46 AM, Chris Angelico <ros...@gmail.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.

Reply via email to