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 repoze.tm 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 repoze.tm > 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 transaction.get().doom() "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 repoze.tm >> 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 just try to work around the issue with a doom. - C _______________________________________________ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev