[ZODB-Dev] [ZODB3.1] easily reproducible deadlock

Christian Robottom Reis kiko at async.com.br
Mon Dec 8 07:49:06 EST 2003


On Sun, Dec 07, 2003 at 12:58:01AM -0800, kapil thangavelu wrote:
> On 12/6/03 10:44 PM, "Shane Hathaway" <shane at zope.com> wrote:
> 
> > On Sun, 7 Dec 2003, Christian Robottom Reis wrote:
> > 
> >> Hmm, are we talking about instantiating two *ClientStorages* in-process?
> >> 
> >> I open multiple connections to the same storage all the time, AFAIUI,
> >> but that's a matter of calling db.open() multiple times.
> > 
> > I believe Dieter is talking about creating two ClientStorages that point
> > to the same ZEO database and attempting to commit changes on both storages
> > in a single transaction.  The ZEO server will try to acquire a lock on the
> > storage twice, resulting in a deadlock.  Note that ZEO has some machinery
> > for breaking locks after a timeout, but that won't work for Dieter.
> > 
> 
> so using setLocalTransaction() on a conn and committing them
> individually/manually would work around this I guess.

Yeah, though think I understand Dieter's problem: he wants to be able to
open a connection to the database at any point in his code without
having to shuffle database/connection objects through constructors (or
even better, stuff them into globals). 

This is a tough problem. The nice thing about most SQL databases is that
when using a language binding you can just conjure a database connection
out of thin air with an address and a username. This is not so with the
ZEO.

I ended up passing a `conn' argument to most UI constructors in our
application [the ones that don't take conn are display-only and don't
require "database access"]. However, I would also have needed to pass in
a connection to my persistent domain object's constructors, and this I
could not accept. Johan and I ended up doing some pretty evil global
hacks (in the form of IndexedCatalog's Registry module) to avoid it, but
it's still not the perfect solution.

You could argue that the connection just encapsulates database
information, and that database address, username and password would
themselves have to be global, but those live nicely in a configuration
module which is accessible globally, whereas connections by definition
can't.

It's perhaps ironic that get_transaction() is in its original form is
global (when using setLocalTransaction() you can't use it, so it's not
as ironic as it could be!) but grabbing a database connection is not.

Take care,
--
Christian Robottom Reis | http://async.com.br/~kiko/ | [+55 16] 261 2331



More information about the ZODB-Dev mailing list