[ZODB-Dev] Commit or lock object accross transactions
Roché Compaan
roche at upfrontsystems.co.za
Wed Jul 16 21:05:52 EDT 2003
* Christian Reis <kiko at async.com.br> [2003-07-16 18:45]:
> On Wed, Jul 16, 2003 at 11:42:43AM -0400, Jeremy Hylton wrote:
> > > The problem with this is that their might be legitimate transactions in
> > > process on other clients.
> >
> > A client that has a transaction in progress will not see the changes
> > committed by another client until the transaction finishes. Changes
> > only become visible at transaction boundaries.
>
> Generating a unique and sequential ID over a global space is not a very
> trivial matter, and I'm not sure all of it is the ZODB's fault in this
> case. There are a number of potential constraints that should to be
> considered. The ones I work with in my app are:
>
> - The ID should be globally unique.
> - The transaction using an allocated ID may be cancelled after it
> is allocated.
> - The ID should be presentable to the end-user in the UI before the
> transaction is commited.
>
> - Scenario 1: Locking primitive. A locking primitive emphasizes the
> first constraint, but it doesn't help the other ones. Orphaned IDs
> would need to be collected and reused (hopefully by the very next
> transaction). Granted, it's a nice feature, and if there is a way
> to implement it in the ZODB, it would be great.
>
> The last constraint is okay here, because the ID is guaranteed to not
> change when commit() happens.
>
> A substantial con here is that the ZODB doesn't provide such a
> primitive, so you'd need to implement it, or using a secondary
> database for IDs.
>
> - Scenario 2: Lazy consistency. Assuming no locking primitive is
> available, the ZODB style of consistency management is lazy -- if
> conflicts do happen (i.e., if two identical IDs are allocated at the
> same time), we can try and resolve the conflict (by assigning
> another ID to the conflicting transaction). Orphaned IDs are less of
> a problem in this scenario (they only appear if you *undo* a
> transaction that was committed, since the ID is guaranteed with the
> commit).
>
> The last constraint is a problem with the lazy model, though, since the
> ID *may* change when the transaction is being committed -- the user that
> wrote down 5563 needs to be notified that when it was committed, a
> conflict was found and it changed to 5564 -- he scratches out the 3 and
> writes a 4 down.
>
> What I recommend, after looking at the options, is analyzing the
> constraints and seeing what your priority is. If a skipped ID every once
> in a while is okay, you don't have to worry about orphaned IDs, which
> simplifies things somewhat. If it's okay to present an ID to the user
> and have it change (presenting a special dialog or page that notifies
> him, or if the user doesn't need to see the ID before committing, that's
> good too.
>
> Someone (I think Casey) once suggested to me using the BTrees' Length to
> define IDs, because it had built-in conflict-resolution (which would
> allocate another value if a conflict happened). [However, because the
> Length only stores the current value, it won't help us with orphaned IDs
> -- you'd need to search through all allocated IDs to check for them.]
Thanks for the pointer to the BTrees' Length class (and your detailed
explanation above).
I am not too concerned about orphaned ids so the BTrees Length class
would be the simplest solution for me. You seem to have tougher
constraints to navigate, so good luck :-)
It seems that a locking primitive could be very useful specifically for
generating sequential unique object ids. Wouldn't it be possible to
prevent orphaned ids if clients requesting ids are queued. If a client
is in front of the queue it locks the object counter, get a new id and
releases the lock. It don't think this will be trivial to implement
though.
--
Roché Compaan
Upfront Systems http://www.upfrontsystems.co.za
More information about the ZODB-Dev
mailing list