Re: deadlock on the same relation

From: "Jim C(dot) Nasby" <jim(at)nasby(dot)net>
To: "Francesco Formenti - TVBLOB S(dot)r(dot)l(dot)" <francesco(dot)formenti(at)tvblob(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: deadlock on the same relation
Date: 2006-01-16 15:19:41
Message-ID: 20060116151941.GL9017@nasby.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Mon, Jan 16, 2006 at 11:57:35AM +0100, Francesco Formenti - TVBLOB S.r.l. wrote:
> Jim C. Nasby wrote:
>
> >On Thu, Jan 12, 2006 at 06:11:32PM +0100, Francesco Formenti - TVBLOB
> >S.r.l. wrote:
> >
> >
> >>I put an ACCESS EXCLUSIVE LOCK on the table of objects at the beginning
> >>of the stored procedure, just to ensure that only one process at a time
> >>can check and set the status of the object, so the status is always
> >>consistent. Is there another way to do that?
> >>
> >>
> >
> >Take a look at SELECT ... FOR UPDATE. It will allow you to block access
> >to a single object without locking the entire table.
> >
> >
>
>
> OK!, thank you. Based on your precious suggestions and reading some more
> documentation, I think I've found the proper way to resolve the problem
> without affecting the performance.
>
> Given an object that can be in status A, B or C, and given the map of
> allowed transitions, such as:
> A--->B
> A--->C
> B--->C
> I can resolve the concurrency problem using a technique based on both
> optimistic lock and Postgres'MVCC strategy.
> Setting the new status, the function set_status(.) will check for both
> starting and ending status, so it will look like:
>
> UPDATE set status=newstatus WHERE (obj_id= $1 AND curr_status= $2)
>
> The MVCC model checks if the WHERE clause is valid before applying the
> changes; since the check is made for object id and for the current
> status, if the status has changed due to the commit of a concurrent
> transaction, the update will fail, and the object status will remain
> consistent.
> I think this should work, I didn't tried it iet. Of course, the proper
> WHERE clause could be placed in the stored procedure, maybe reproducing
> the finite state machine of the object (e.g., if I want to put the
> object in status C, I will check WHERE obj_id= $1 AND curr_status <>
> new_status, rather than curr_status = $2).

Yes, simply checking for a valid current status will allow this to work.
You could also put the state transition information into a check
constraint to enforce the state machine. At a former job I actually had
the states named (in an external table), and did the check with a
trigger that read the valid transition information from another table.

> So, I will not use explicit locks here. However, I'm still curious about
> the model of locking, because I don't understand the reason of the
> deadlock on the same relation. How does it works under the hood? I
> assumed a model like non-recursive mutex locking: I lock the mutex
> accessing to a protected area, and other processes call acquire(.) and
> wait for the mutex to be freed; so, there's a queue. As a test, I tried
> to put an access exclusive lock at the beginning of all my stored
> procedures, and to increase the deadlock_timeout, trying to enlarge the
> waiting buffer of the queue, but the result has been awful! There were
> deadlock on ALL of the stored procedures! :-(
> Is the queue model valid for locks? Or something like try_acquire(.)
> rather than acquire(.) happens, so, if the mutex is locked, an error is
> raised and no queue is made?

I'm not a C coder, so I can't help you there. What I can tell you is
that anytime you're updating multiple things in the same transaction
you're at risk for a deadlock. In your case it was probably due to
either updating multiple rows in the same table in a different order
(ie: transaction 1 updates ID 1, 3, 5 while transaction 2 updates 5, 7,
1 - risk of deadlock), or there were triggers involved that could
operate against other objects (remember that RI is done as triggers).
--
Jim C. Nasby, Database Architect jim(at)nasby(dot)net
512.569.9461 (cell) http://jim.nasby.net

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Zlatko Matić 2006-01-16 15:25:46 Re: visual query builder for Postgres?
Previous Message Tony Caduto 2006-01-16 14:01:08 Re: visual query builder for Postgres?