I'm not sure if carrying a transaction across multiple requests is possible,
mainly because you can't be assured of getting the same connection to the
database across requests.
Looking through the code, it does appear to be possible to override the
default commit behavior at the end of a successful response. gluon/main.py,
around line 470:
if response._custom_commit:
response._custom_commit()
else:
BaseAdapter.close_all_instances('commit')
So in your controller you could technically do something like this:
def my_action():
def no_commit():
pass
response._custom_commit = no_commit
db.table.insert(...)
return dict(...)
and web2py would execute your empty "no_commit" function rather than the
normal db commit. However, the db connection will probably get closed anyway
and the transaction lost unless you have connection pooling enabled. And
with a pool, the next time a request comes in, it's likely that you will get
assigned a different connection to the database which does not have the
transaction state that you left behind. Perhaps even more surprisingly, if
somebody else gets your old db connection mid-transaction and their action
does a normal commit, your incomplete data will get written to the database.
This is all guesswork on my part - it's possible web2py has some clever way
of handling this that I don't know about. But for cases like multi-page
wizards, it seems preferable to build up your data structure in the session,
and then insert and commit after the final confirmation page. I'm having
trouble thinking of a case where data size would prohibit this. Perhaps if
one or more large file uploads are part of the process -- but in that case
the file contents are sitting the uploads folder, and you can just store the
path of the stored file in your session structure.
If you have an example where this breaks down, it would be interesting to
consider.
Cheers,
Kevin