| 269 | |
| 270 | #################### |
| 271 | # CONTEXT MANAGERS # |
| 272 | #################### |
| 273 | @contextlib.contextmanager |
| 274 | def transaction(): |
| 275 | """Context manager for executing something in the context of a database |
| 276 | transaction. A transaction is started and the nested block executed. If |
| 277 | no exceptions are raised, the transaction is committed. Otherwise, the |
| 278 | transaction is rolled back and the exception re-raised.""" |
| 279 | try: |
| 280 | enter_transaction_management() |
| 281 | managed(True) |
| 282 | try: |
| 283 | yield |
| 284 | except: |
| 285 | # The nested block threw an exception, roll back |
| 286 | if is_dirty(): |
| 287 | rollback() |
| 288 | raise |
| 289 | else: |
| 290 | # The nested block succeeded, commit |
| 291 | if is_dirty(): |
| 292 | commit() |
| 293 | finally: |
| 294 | leave_transaction_management() |