server/session.py
changeset 7454 1090724f28ed
parent 7406 e772a2c57b00
parent 7451 48ba5f0c11de
child 7514 32081892850e
--- a/server/session.py	Fri May 27 13:57:25 2011 +0200
+++ b/server/session.py	Mon Jun 06 15:03:00 2011 +0200
@@ -75,6 +75,25 @@
     return req.is_internal_session
 
 
+class transaction(object):
+    """context manager to enter a transaction for a session: when exiting the
+    `with` block on exception, call `session.rollback()`, else call
+    `session.commit()` on normal exit
+    """
+    def __init__(self, session, free_cnxset=True):
+        self.session = session
+        self.free_cnxset = free_cnxset
+
+    def __enter__(self):
+        pass
+
+    def __exit__(self, exctype, exc, traceback):
+        if exctype:
+            self.session.rollback(free_cnxset=self.free_cnxset)
+        else:
+            self.session.commit(free_cnxset=self.free_cnxset)
+
+
 class hooks_control(object):
     """context manager to control activated hooks categories.
 
@@ -237,6 +256,16 @@
         return '<%ssession %s (%s 0x%x)>' % (
             self.cnxtype, unicode(self.user.login), self.id, id(self))
 
+    def transaction(self, free_cnxset=True):
+        """return context manager to enter a transaction for the session: when
+        exiting the `with` block on exception, call `session.rollback()`, else
+        call `session.commit()` on normal exit.
+
+        The `free_cnxset` will be given to rollback/commit methods to indicate
+        wether the connections set should be freed or not.
+        """
+        return transaction(self, free_cnxset)
+
     def set_tx_data(self, txid=None):
         if txid is None:
             txid = threading.currentThread().getName()