[Zope-dev] [Bug] Zope's transaction behaviour flawed
Steve Alexander
steve@cat-box.net
Mon, 03 Feb 2003 10:44:46 +0200
Chris McDonough wrote:
> I am +1 on this. I suspect that before committing, though, we should
> ask people who make use of Zope's transaction manager in "advanced"
> ways like Phillip Eby.
As I noted in the Collector issue, I believe this change is a good idea
overall. As Chris suggests, we should take note of users of ZPatterns
and TransactionAgents (and other add-ons?), as these do things at
transaction boundaries such as clear computed fields. The error handlers
currently in use may expect these computed fields to be still available.
By conincidence I'm implementing something similar for error handling in
Zope 3 right now.
Here's the kind of thing I'm doing in zope 3, using the same notation
Dieter used. First, the simple case where the error handler will
definitely not need to alter any state:
## request starts
transaction.begin()
try:
object= REQUEST.traverse(...)
result = mapply(object,...)
transaction.commit()
except:
try:
try:
result = handle_error()
except:
result = default_handle_error()
# Zope's default error handling
# it must not have side effects
finally:
transaction.abort()
request.response.setBody(result)
## request ends
If there's an exception handler that has side-effects, it must
explicitly say so, and we get this:
## request starts
transaction.begin()
try:
object= REQUEST.traverse(...)
result = mapply(object,...)
transaction.commit()
except:
try:
try:
# this call returns a special
# 'I have side-effects' token.
result = handle_error()
except:
result = default_handle_error()
# Zope's default error handling
# it should not have side effects
finally:
transaction.abort()
if result is I_HAVE_SIDE_EFFECTS:
transaction.begin()
transaction.note('%s (application error handling)'
% '/'.join(object.getPhysicalPath))
try:
result = handle_error_with_sideeffects()
transaction.commit()
except:
try:
result = default_handle_error()
# Zope's default error handling
# it should not have side effects
finally:
transaction.abort()
else:
request.response.setBody(result)
## request ends
--
Steve Alexander