I followed the tutorial on http://docs.pylonsproject.org/docs/pyramid/en/latest/tutorials/wiki/index.html
I know that when I add or change persistent objects (in this case Page objects), the change will not be persisted until transaction.commit()
is called. And in order to cancel changes, I can call transaction.abort()
.
In the tutorial, however, these calls are not shown in the view callables. I assume that there is some middleware in place that will catch exceptions and call .abort()
or call .commit()
just before sending the HTTP response, but I don't see any mention of it anywhere in the code or config files.
Could you point me in the right direction? I just need to know what happens behind the scenes, so I know if I need to add something myself
The pyramid_tm
package is used; it installs a Tween that manages the transaction.
It simply starts a transaction for every request, and if the request was successful the transaction is committed, and aborted otherwise.
From the documentation:
At the beginning of a request a new transaction is started using the
transaction.begin()
function. Once the request has finished all of its works (ie views have finished running), a few checks are tested:
- Did some a
transaction.doom()
cause the transaction to become “doomed”? if so,transaction.abort()
.- Did an exception occur in the underlying code? if so,
transaction.abort()
If thetm.commit_veto
configuration setting was used, did the commit veto callback, called with the response generated by the application, return a result that evaluates toTrue
? if so,transaction.abort()
.If none of these checks calls
transaction.abort()
then the transaction is instead committed usingtransaction.commit()
.
It'll also retry requests (re-start them from the beginning) if there was a retryable exception (such as a ZODB commit conflict):
When the transaction manager calls the downstream handler, if the handler raises a “retryable” exception, the transaction manager can be configured to attempt to call the downstream handler again with the same request, in effect “replaying” the request.
This behaviour is disabled by default; you can set the tm.attempts
option to a number larger than 1 to enable it.