No.

I have tested all cases, the code I quoted is complete and minimal. All
operations are non-blocking (count incrementation is non-blocking, insertion
with a foreign key is non-blocking too), but it still generates a deadlock
time to time. Deletion of the foreign key constraint completely solves the
problem.

I am using the latest version of Postgres.

You said "I'm pretty sure that recent versions check to see if the key
actually changed", but how could it be if Postgres uses a row-level locking,
not field-level locking? Seems it cannot check what fields are changed, it
locks the whole row.


On 8/15/07, Decibel! <[EMAIL PROTECTED]> wrote:
>
> On Fri, Aug 10, 2007 at 09:38:36PM +0400, Dmitry Koterov wrote:
> > Hello.
> >
> > I have a number of deadlock because of the foreign key constraint:
> >
> > Assume we have 2 tables: A and B. Table A has a field fk referenced to
> > B.idas a foreign key constraint.
> >
> >
> > -- transaction #1
> > BEGIN;
> > ...
> > INSERT INTO A(x, y, fk) VALUES (1, 2, 666);
> > ...
> > END;
> >
> >
> > -- transaction #2
> > BEGIN;
> > UPDATE B SET z = z + 1 WHERE id = 666;
> > ...
> > UPDATE B SET z = z + 1 WHERE id = 666;
> > ...
> > UPDATE B SET z = z + 1 WHERE id = 666;
> > END;
> >
> >
> > You see, table A is only inserted, and table B is only updated their
> field z
> > on its single row.
> > If we execute a lot of these transactions concurrently using multiple
> > parellel threads, sometimes we have a deadlock:
> >
> > DETAIL:  Process 6867 waits for ShareLock on transaction 1259392;
> blocked by
> > process 30444.
> >     Process 30444 waits for ShareLock on transaction 1259387; blocked by
> > process 6867.
> > CONTEXT:  SQL statement "SELECT 1 FROM ONLY "public"."B" x WHERE "id" =
> $1
> > FOR SHARE OF x"
> >
> > If I delete the foreign key constraint, all begins to work fine.
> > Seems Postgres thinks that "UPDATE B SET z = z + 1 WHERE id = 666" query
> may
> > modify B.id field and touch A.fk, so it holds the shareable lock on it.
>
> What version are you running? I'm pretty sure that recent versions check
> to see if the key actually changed.
>
> > The question is: is it possible to KEEP this foreign key constraint, but
> > avoid deadlocks?
>
> I'm pretty sure that the deadlock is actually being caused by your
> application code, likely because you're doing multiple updates within
> one transaction, but not being careful about the id order you do them
> in.
> --
> Decibel!, aka Jim Nasby                        [EMAIL PROTECTED]
> EnterpriseDB      http://enterprisedb.com      512.569.9461 (cell)
>
>

Reply via email to