Context manager for atomic SQLite transactions. Acquires a write lock immediately via BEGIN IMMEDIATE (configured by engine event hooks), preventing stale reads in read-modify-write patterns. This is essential for preventing race conditions in parallel mode. Args: session_m
(session_maker)
| 503 | |
| 504 | @contextmanager |
| 505 | def atomic_transaction(session_maker): |
| 506 | """Context manager for atomic SQLite transactions. |
| 507 | |
| 508 | Acquires a write lock immediately via BEGIN IMMEDIATE (configured by |
| 509 | engine event hooks), preventing stale reads in read-modify-write patterns. |
| 510 | This is essential for preventing race conditions in parallel mode. |
| 511 | |
| 512 | Args: |
| 513 | session_maker: SQLAlchemy sessionmaker |
| 514 | |
| 515 | Yields: |
| 516 | SQLAlchemy session with automatic commit/rollback |
| 517 | |
| 518 | Example: |
| 519 | with atomic_transaction(session_maker) as session: |
| 520 | # All reads in this block are protected by write lock |
| 521 | feature = session.query(Feature).filter(...).first() |
| 522 | feature.priority = new_priority |
| 523 | # Commit happens automatically on exit |
| 524 | """ |
| 525 | session = session_maker() |
| 526 | try: |
| 527 | yield session |
| 528 | session.commit() |
| 529 | except Exception: |
| 530 | try: |
| 531 | session.rollback() |
| 532 | except Exception: |
| 533 | pass # Don't let rollback failure mask original error |
| 534 | raise |
| 535 | finally: |
| 536 | session.close() |
no test coverage detected