[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