Commit 1eeff781 authored by Chris McDonough's avatar Chris McDonough

Merge from 2.7 branch:

Collector 789:  Zope's transaction behavior flawed.
                                                                                
Historically, errors that made it up to the publisher have run outside the
context of a transaction.  This has caused problems for applications which
expect to be able to write to the database (if only temporarily, before
transaction.abort() is eventually called).
                                                                                
With this patch, we allow the error to execute in the same transaction as
the "main" request, and abort only after the error has executed.
parent 5a38c6e8
...@@ -119,8 +119,6 @@ def publish(request, module_name, after_list, debug=0, ...@@ -119,8 +119,6 @@ def publish(request, module_name, after_list, debug=0,
return response return response
except: except:
if transactions_manager:
transactions_manager.abort()
# DM: provide nicer error message for FTP # DM: provide nicer error message for FTP
sm = None sm = None
...@@ -138,19 +136,29 @@ def publish(request, module_name, after_list, debug=0, ...@@ -138,19 +136,29 @@ def publish(request, module_name, after_list, debug=0,
if parents: if parents:
parents=parents[0] parents=parents[0]
try: try:
return err_hook(parents, request, response = err_hook(parents, request,
sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2],
)
except Retry:
# We need to try again....
if not request.supports_retry():
return err_hook(parents, request,
sys.exc_info()[0], sys.exc_info()[0],
sys.exc_info()[1], sys.exc_info()[1],
sys.exc_info()[2], sys.exc_info()[2],
) )
if transactions_manager:
transactions_manager.abort()
return response
except Retry:
if not request.supports_retry():
response = err_hook(parents, request,
sys.exc_info()[0],
sys.exc_info()[1],
sys.exc_info()[2],
)
if transactions_manager:
transactions_manager.abort()
return response
if transactions_manager:
transactions_manager.abort()
newrequest=request.retry() newrequest=request.retry()
request.close() # Free resources held by the request. request.close() # Free resources held by the request.
try: try:
...@@ -159,6 +167,8 @@ def publish(request, module_name, after_list, debug=0, ...@@ -159,6 +167,8 @@ def publish(request, module_name, after_list, debug=0,
newrequest.close() newrequest.close()
else: else:
if transactions_manager:
transactions_manager.abort()
raise raise
......
...@@ -179,8 +179,6 @@ def zpublisher_exception_hook(published, REQUEST, t, v, traceback): ...@@ -179,8 +179,6 @@ def zpublisher_exception_hook(published, REQUEST, t, v, traceback):
published=app.__bobo_traverse__(REQUEST).__of__( published=app.__bobo_traverse__(REQUEST).__of__(
RequestContainer(REQUEST)) RequestContainer(REQUEST))
get_transaction().begin() # Just to be sure.
published=getattr(published, 'im_self', published) published=getattr(published, 'im_self', published)
while 1: while 1:
f=getattr(published, 'raise_standardErrorMessage', None) f=getattr(published, 'raise_standardErrorMessage', None)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment