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 next
---- ----
* Per-call database transaction handling.
* :class:`Unset` is now imported in the wsme module * :class:`Unset` is now imported in the wsme module
* Attributes of complex types can now have a different name in * 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): class WSRoot(object):
""" """
Root controller for webservices. Root controller for webservices.
:param protocols: A list of protocols to enable (see :meth:`addprotocol`) :param protocols: A list of protocols to enable (see :meth:`addprotocol`)
:param webpath: The web path where the webservice is published. :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._debug = True
self._webpath = webpath self._webpath = webpath
self.protocols = [] self.protocols = []
self.transaction = transaction
if self.transaction is True:
import transaction
self.transaction = transaction
for protocol in protocols: for protocol in protocols:
self.addprotocol(protocol) self.addprotocol(protocol)
self._api = None self._api = None
def begin(self):
if self.transaction:
return self.transaction.begin()
else:
return DummyTransaction()
def addprotocol(self, protocol, **options): def addprotocol(self, protocol, **options):
""" """
Enable a new protocol on the controller. Enable a new protocol on the controller.
@ -104,7 +138,13 @@ class WSRoot(object):
if arg.mandatory and arg.name not in kw: if arg.mandatory and arg.name not in kw:
raise exc.MissingArgument(arg.name) 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 \ if context.funcdef.protocol_specific \
and context.funcdef.return_type is None: and context.funcdef.return_type is None: