| 1 |
Transaction support for Gaphor |
|---|
| 2 |
============================== |
|---|
| 3 |
|
|---|
| 4 |
Transaction support is located in module gaphor.transaction: |
|---|
| 5 |
|
|---|
| 6 |
>>> from gaphor import transaction |
|---|
| 7 |
|
|---|
| 8 |
The Transaction class is used mainly to signal the begin and end of a transaction. This is done by the TransactionBegin, TransactionCommit and TransactionRollback events: |
|---|
| 9 |
|
|---|
| 10 |
>>> from zope import component |
|---|
| 11 |
>>> @component.adapter(transaction.TransactionBegin) |
|---|
| 12 |
... def transaction_begin_handler(event): |
|---|
| 13 |
... print 'tx begin' |
|---|
| 14 |
>>> component.provideHandler(transaction_begin_handler) |
|---|
| 15 |
|
|---|
| 16 |
Same goes for commit and rollback events: |
|---|
| 17 |
|
|---|
| 18 |
>>> @component.adapter(transaction.TransactionCommit) |
|---|
| 19 |
... def transaction_commit_handler(event): |
|---|
| 20 |
... print 'tx commit' |
|---|
| 21 |
>>> component.provideHandler(transaction_commit_handler) |
|---|
| 22 |
>>> @component.adapter(transaction.TransactionRollback) |
|---|
| 23 |
... def transaction_rollback_handler(event): |
|---|
| 24 |
... print 'tx rollback' |
|---|
| 25 |
>>> component.provideHandler(transaction_rollback_handler) |
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
A Transaction is started by initiating a Transaction instance: |
|---|
| 29 |
|
|---|
| 30 |
>>> tx = transaction.Transaction() |
|---|
| 31 |
tx begin |
|---|
| 32 |
|
|---|
| 33 |
On success, a transaction can be committed: |
|---|
| 34 |
|
|---|
| 35 |
>>> tx.commit() |
|---|
| 36 |
tx commit |
|---|
| 37 |
|
|---|
| 38 |
After a commit, a rollback is no longer allowed (the transaction is closed): |
|---|
| 39 |
|
|---|
| 40 |
>>> tx.rollback() |
|---|
| 41 |
... # doctest: +ELLIPSIS |
|---|
| 42 |
Traceback (most recent call last): |
|---|
| 43 |
... |
|---|
| 44 |
TransactionError: No Transaction on stack. |
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
Transactions may be nested: |
|---|
| 48 |
|
|---|
| 49 |
>>> tx = transaction.Transaction() |
|---|
| 50 |
tx begin |
|---|
| 51 |
>>> tx2 = transaction.Transaction() |
|---|
| 52 |
>>> tx2.commit() |
|---|
| 53 |
>>> tx.commit() |
|---|
| 54 |
tx commit |
|---|
| 55 |
|
|---|
| 56 |
Transactions should be closed in the right order (subtransactions first): |
|---|
| 57 |
|
|---|
| 58 |
>>> tx = transaction.Transaction() |
|---|
| 59 |
tx begin |
|---|
| 60 |
>>> tx2 = transaction.Transaction() |
|---|
| 61 |
>>> tx.commit() |
|---|
| 62 |
... # doctest: +ELLIPSIS |
|---|
| 63 |
Traceback (most recent call last): |
|---|
| 64 |
... |
|---|
| 65 |
TransactionError: Transaction on stack is not the transaction being closed. |
|---|
| 66 |
>>> tx2.commit() |
|---|
| 67 |
>>> tx.commit() |
|---|
| 68 |
tx commit |
|---|
| 69 |
|
|---|
| 70 |
|
|---|
| 71 |
The transactional decorator can be used to mark functions as transactional: |
|---|
| 72 |
|
|---|
| 73 |
>>> @transaction.transactional |
|---|
| 74 |
... def a(): |
|---|
| 75 |
... print 'do something' |
|---|
| 76 |
>>> a() |
|---|
| 77 |
tx begin |
|---|
| 78 |
do something |
|---|
| 79 |
tx commit |
|---|
| 80 |
|
|---|
| 81 |
If an exception is raised from within the decorated function a rollback is |
|---|
| 82 |
performed: |
|---|
| 83 |
|
|---|
| 84 |
>>> @transaction.transactional |
|---|
| 85 |
... def a(): |
|---|
| 86 |
... raise IndexError, 'bla' |
|---|
| 87 |
>>> a() |
|---|
| 88 |
... # doctest: +ELLIPSIS |
|---|
| 89 |
Traceback (most recent call last): |
|---|
| 90 |
... |
|---|
| 91 |
IndexError: bla |
|---|
| 92 |
>>> transaction.Transaction._stack |
|---|
| 93 |
[] |
|---|
| 94 |
|
|---|
| 95 |
All transactions are marked for rollback once an exception is raised: |
|---|
| 96 |
|
|---|
| 97 |
>>> tx = transaction.Transaction() |
|---|
| 98 |
tx begin |
|---|
| 99 |
>>> a() |
|---|
| 100 |
... # doctest: +ELLIPSIS |
|---|
| 101 |
Traceback (most recent call last): |
|---|
| 102 |
... |
|---|
| 103 |
IndexError: bla |
|---|
| 104 |
>>> tx._need_rollback |
|---|
| 105 |
True |
|---|
| 106 |
>>> tx.commit() |
|---|
| 107 |
tx rollback |
|---|
| 108 |
|
|---|