[ZODB-Dev] Sequences and ZODB conflicts

Christian Reis kiko@async.com.br
Tue, 28 Jan 2003 23:27:54 -0200


I've got something of an odd problem that I think others that use the
ZODB in a multi-connection/multi-user environment may have run into
before. Summarizing my question: How should we handle "locking" of
user-level data through the ZODB?

The scenario is a simple one: a domain object has an attribute that we
will call "code", which is a sequential number that should be
incremented for each new object instantiated. Let's say the counter is a
simple persistent integer attached to a counter object in the database,
and that you can issue next() to it and get the next integer.

When we have two connections to the database, there is a natural
concurrency issue. The issue occurs because the two connections see
their own copies of the counter object, and next() will issue the same
ID to both. The first connection to commit() will succeed, but the
second will fail with a ConflictError. 

Now, just before commit() is called and the exception raised, my
connection._transaction._objects is chock-full of instances. commit() is
called, and ZODB.POSException.ConflictError is raised.

Now the behaviour after this ConflictError is interesting. After it is
raised, I expected all the instances in my connections to be invalidated
(reverted to None) and that a subsequent commit() would fail. Wrong!

The object reference I created (during the conflicting connection) is
not "uncreated" - the name still points to a valid persistent object.
However, _transaction._objects is now empty. Have I lost the chance to
save this instance forever, or can I do something magic, and try again?
All that conflicted was the Sequence, after all.

Take care,
--
Christian Reis, Senior Engineer, Async Open Source, Brazil.
http://async.com.br/~kiko/ | [+55 16] 261 2331 | NMFL