[ZODB-Dev] RE: [Zope-Annce] ZODB 3.2.4 release candidate1released

Tim Peters tim at zope.com
Thu Sep 9 22:34:50 EDT 2004


...

[Tim Peters]
>> It not that it's the only thing you can do with it, it's that you *must*
>> explicitly abort() or begin()

[Chris McDonough]
> Er, why would begin() be allowed?

Because begin() implies abort() -- abort() is the first thing the
implementation of begin() does.  Until very recently, there was a gross bug
in this respect in pre-3.3 ZODBs, where thanks to a misguided optimization,
begin() skipped the abort() if the only changes pending were in
subtransactions.

That's *part* of what made the 2.7.2 "publisher neglected to abort() before
closing the connection" bug as horrid as it was:  I'm told that Zope still
did a begin() after opening a connection again, but even if it got back the
same Connection object (which is likely), begin() failed to do an abort() in
the one case that did the worst damage!  That part was a ZODB bug.

> I think I know why: because in ZODB 3.3, begin() returns a spanking-new
> transaction object instead of recycling the old one, and we don't care
> that the old one wasn't aborted, because it essentially disappears when
> the last reference to it is released?

Nope, and not even a hack:  it's that, semantically, begin() *means* "I want
a new transaction -- and if I left crap behind in the current transaction,
please get rid of it first".

...

> Tim has explained that the current behavior when a commit exception is
> encountered is to abort all jars in the transaction and raise the
> exception.  That's fine, but when the commit exception is suppressed, the
> existing transaction remains in a usable state and there's no indication
> that a failure ever occurred.  It's then possible for code that assumes
> prior changes to persistent state in the same transaction were performed
> successfully to do more changes and later commit its work without
> incident.   I'd like that this wasn't the case, which is why I say +1 to
> making it impossible to commit a transaction that has already failed a
> commit once.

A practical question:  is it conceivable that this ever happens in Zope?  I
understand that all sorts of icky things can happen because implementations
of this and that may suppress all sorts of exceptions, but I'm finding it
hard to believe that, e.g., any call to hasattr() ends up calling code that
tries to do a commit().  Aren't there just a relative handful of commit()
sites in Zope?  I don't know -- but I sure hope so.

> Basically, if a commit failure occurs, the transaction needs to be put
> into a doomed state.  And if all you can do with a failed transaction is
> call abort() or begin() on it, it's doomed, but any other way that this
> goal can be reached is fine by me too.

What is the universe of things "you can do with a transaction"?  Marking a
Transaction object as doomed would not, for example, prevent you from
loading objects from the database.  The Transaction object isn't involved in
that.  The only effect I can think of would be to prevent you from doing
another commit().  So let's get clear about *everything* you would want to
see happen, if "prevent you from doing another commit()" isn't all you want.



More information about the ZODB-Dev mailing list