| | 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() |