You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
status, context_data, version = await storage.load_saga_state(saga_id)
50
50
history = await storage.get_step_history(saga_id)
51
51
```
52
52
@@ -58,7 +58,7 @@ history = await storage.get_step_history(saga_id)
58
58
59
59
## SQLAlchemy Storage
60
60
61
-
Database-backed implementation for production.
61
+
Database-backed implementation for production. It uses a session factory to manage transactions internally, ensuring that every step is committed immediately ("checkpointing").
62
62
63
63
### Database Schema
64
64
@@ -67,6 +67,7 @@ Database-backed implementation for production.
1. Each method (`create_saga`, `log_step`, etc.) opens a new session.
138
+
2. The operation is performed.
139
+
3. `session.commit()`is called immediately.
140
+
4. The session is closed.
141
+
142
+
This design ensures:
143
+
144
+
-**Crash Safety:** Even if the application crashes mid-saga, all completed steps are safely persisted.
145
+
-**Connection Efficiency:** Connections are returned to the pool immediately after each operation.
146
+
-**Isolation:** Saga storage operations don't interfere with your business logic transactions.
147
+
148
+
### Concurrency Control
149
+
150
+
The storage implementation provides two mechanisms to handle concurrency in distributed environments:
151
+
152
+
#### 1. Optimistic Locking (Versioning)
153
+
154
+
To prevent "lost updates" when multiple steps might update the context simultaneously (though sagas typically execute sequentially), the `version` column is used.
155
+
156
+
-`update_context` accepts an optional `current_version`.
157
+
- If provided, the storage checks if`version == current_version`.
158
+
- If matched, it updates the context and increments the version (`version +1`).
159
+
- If not matched, it raises `SagaConcurrencyError`, indicating the state was modified by another process.
160
+
161
+
#### 2. Row Locking (Recovery Safety)
162
+
163
+
When recovering a saga (e.g., after a crash), it is critical that only one worker picks up the saga to avoid duplicate execution.
0 commit comments