Add a per-call transaction management

This commit is contained in:
Christophe de Vienne 2012-01-18 17:57:58 +01:00
parent 3f905d5b1f
commit 771f30092f
2 changed files with 44 additions and 2 deletions

View File

@ -4,6 +4,8 @@ Changes
next
----
* Per-call database transaction handling.
* :class:`Unset` is now imported in the wsme module
* Attributes of complex types can now have a different name in

View File

@ -25,22 +25,56 @@ html_body = """
"""
class DummyTransaction:
def commit(self):
pass
def abort(self):
pass
class WSRoot(object):
"""
Root controller for webservices.
:param protocols: A list of protocols to enable (see :meth:`addprotocol`)
:param webpath: The web path where the webservice is published.
:type transaction: A `transaction
<http://pypi.python.org/pypi/transaction>`_-like
object or ``True``.
:param transaction: If specified, a transaction will be created and
handled on a per-call base.
This option *can* be enabled along with `repoze.tm2
<http://pypi.python.org/pypi/repoze.tm2>`_
(it will only make it void).
If ``True``, the default :mod:`transaction`
module will be imported and used.
"""
def __init__(self, protocols=[], webpath=''):
def __init__(self, protocols=[], webpath='', transaction=None):
self._debug = True
self._webpath = webpath
self.protocols = []
self.transaction = transaction
if self.transaction is True:
import transaction
self.transaction = transaction
for protocol in protocols:
self.addprotocol(protocol)
self._api = None
def begin(self):
if self.transaction:
return self.transaction.begin()
else:
return DummyTransaction()
def addprotocol(self, protocol, **options):
"""
Enable a new protocol on the controller.
@ -104,7 +138,13 @@ class WSRoot(object):
if arg.mandatory and arg.name not in kw:
raise exc.MissingArgument(arg.name)
result = context.func(**kw)
txn = self.begin()
try:
result = context.func(**kw)
txn.commit()
except:
txn.abort()
raise
if context.funcdef.protocol_specific \
and context.funcdef.return_type is None: