root/gaphor/tags/gaphor-0.13.0/gaphor/transaction.py

Revision 2100, 1.9 kB (checked in by arj..@yirdis.nl, 1 year ago)

Allow for creation of top-level packages and diagrams.

Line 
1 """
2 Transation support for Gaphor
3 """
4
5 from zope import interface, component
6 from gaphor.interfaces import ITransaction
7 from gaphor.event import TransactionBegin, TransactionCommit, TransactionRollback
8
9 def transactional(func):
10     def _transactional(*args, **kwargs):
11         tx = Transaction()
12         try:
13             func(*args, **kwargs)
14         except Exception, e:
15             log.error('Transaction terminated due to an exception, performing a rollback', e)
16             try:
17                 tx.rollback()
18             except Exception, e:
19                 log.error('Rollback failed', e)
20             raise
21         else:
22             tx.commit()
23     return _transactional
24
25 class TransactionError(Exception):
26     """
27     Errors related to the transaction module.
28     """
29
30
31 class Transaction(object):
32     interface.implements(ITransaction)
33
34     _stack= []
35
36     def __init__(self):
37         self._need_rollback = False
38         if not self._stack:
39             component.handle(TransactionBegin())
40         self._stack.append(self)
41
42     def commit(self):
43         self._close()
44 #        if self._need_rollback:
45 #            log.warning('Tried to commit a transaction already marked for rollback.')
46         if not self._stack:
47             if self._need_rollback:
48                 component.handle(TransactionRollback())
49             else:
50                 component.handle(TransactionCommit())
51
52     def rollback(self):
53         self._close()
54         # Mark every tx on the stack for rollback
55         for tx in self._stack:
56             tx._need_rollback = True
57         if not self._stack:
58             component.handle(TransactionRollback())
59
60     def _close(self):
61         try:
62             last = self._stack.pop()
63         except IndexError:
64             raise TransactionError, 'No Transaction on stack.'
65         if last is not self:
66             self._stack.append(last)
67             raise TransactionError, 'Transaction on stack is not the transaction being closed.'
68
69
70 # vim: sw=4:et:ai
Note: See TracBrowser for help on using the browser.