[ZODB-Dev] ZODB 3.2.4 ConnectionStateError

Tim Peters tim at zope.com
Mon Nov 15 10:15:47 EST 2004


[Syver Enstad]
>>> The reason I am concerned about this is that I have a relatively large
>>> web based system using ZODB and I don't want the entire web server to
>>> go down just because one of the web pages has a bug in it. Maybe one
>>> should always do connection.getTransaction().abort() before closing the
>>> connection?

[Tim Peters]
>> Some people would say that Zope is also a relatively large web based
>> system using ZODB that doesn't want to go down just because a web page
>> has a bug in it, and that's what it does <wink>.  All the examples above
>> still *appear* to allow the whole app to go down if a conflict error
>> occurs (because there's no code in them to catch, deal with, and
>> suppress conflict errors).

[Syver]
> Isn't transaction.abort() enough to deal with a conflict error?

In all the examples, abort() was done in a "finally": clause, or in an
"except:" clause that ended with "raise".  A "finally:" clause is executed
regardless of whether an exception occurs, but if an exception does occur,
"finally:" doesn't suppress the exception.  When the "finally:" suite ends,
the exception is propagated (unless an exception also occurs during the
"finally:" suite's execution, in which case that new exception gets
propagated instead).  This is about Python semantics, BTW, not really about
ZODB.  For example,

>>> try:
...     1/0
... finally:
...     print "got into the finally clause with an exception"
got into the finally clause with an exception
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
ZeroDivisionError: integer division or modulo by zero
>>>

So if you experience a conflict error during the innermost "try:", or during
the commit(), in the following, it will propagate beyond all the code shown
here:

[one of your examples]
> connection = db.open()
> try:
>     try:
>         for each in connection.root()['mycollection']:
>             each.setSomeState(arg)
>     except:
>         connection.getTransaction().abort()
>         raise
>     connection.getTransaction().commit()
> finally:
>     connection.close()

If there isn't *more* code at a higher level (no more than this was shown,
so I can't guess) to catch and suppress such conflict errors, the app will
indeed end the first time a conflict error occurs.



More information about the ZODB-Dev mailing list