Re-added to list...

Alberto Valverde wrote:
>> Mark Ramm wrote:
>>> So, we're finally getting around to handling transactions in
>>> middleware in tg2, and Alberto and I have been playing with different
>>> variations on the theme, and ultimately I think it might be
>>> good if we had a transaction middleware that provided a bit more
>>> configurability about when it rolls back transactions.
>> +1
>>> Alberto added something which checked the HTTP status code for error
>>> codes and rolled back when the app indicated that an error had
>>> occurred (useful when there's middleware that catches and handles
>>> python exceptions), and I was playing with the idea of setting some
>>> kind of semi-standard parameter in the environ that signals that
>>> there's been an error somewhere and the transaction should be rolled
>>> back.
>> There is an existing pattern for this if you can get a hold of the
>> transaction
>> object itself in app code:  transaction.doom()
> This is good for the cases where the middleware stacked below
> knows about the transaction, but worthless otherwise.

Any app code can doom the current transaction, actually by an import and a 
couple of function calls:

import transaction

"t" is a transaction.Transaction object then representing the current 
transaction.  It is effectively a "thread local" (although it's not a Python 
threading.local, as the transaction package was created before that existed).

>> If that's not convenient, how about a way to define a "commit veto" hook?
>> Then
>> you could do whatever you liked with the environ, status, or response
>> headers to
>> determine that you shouldn't commit. An implementation might be:
>> def commit_veto(environ, status, response_headers):
>>      if not status.startswith('2'):
>>          return True
>> It would be called by the middleware just before it's about to commit.  If
>> the
>> commit veto hook return True, it would mean "don't commit".  Tthe
>> middleware
>> would capture the status and header output and do:
>> if transaction.isDoomed() or self.commit_veto(environ, status, headers):
>>      self.abort()
>> The commit_veto function would be passed as an argument to the
>> middleware constructor, so you'd create a TM via:
>> txn_managed_app = repoze.tm2.TM(app, commit_veto)
> This would be prefect :)

OK, I'll try to add it in some form shortly (or you can if you like too, I'd be 
happy to accept a patch or give commit access).  In the meantime, you might 
try to work around the issue with a doom.

- C

Repoze-dev mailing list

Reply via email to