sochdb_storage/transaction.rs
1// SPDX-License-Identifier: AGPL-3.0-or-later
2// SochDB - LLM-Optimized Embedded Database
3// Copyright (C) 2026 Sushanth Reddy Vanagala (https://github.com/sushanthpy)
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Affero General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Affero General Public License for more details.
14//
15// You should have received a copy of the GNU Affero General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18//! Unified Transaction Coordinator
19//!
20//! This module defines the canonical transaction management interface for SochDB.
21//! It consolidates the functionality of multiple transaction managers:
22//!
23//! ## Implementation Guide
24//!
25//! There are THREE transaction manager implementations in SochDB. Here's when to use each:
26//!
27//! ### 1. `MvccTransactionManager` (wal_integration.rs) - **RECOMMENDED FOR PRODUCTION**
28//!
29//! Full-featured transaction manager with:
30//! - ✅ WAL-based durability (fsync on commit)
31//! - ✅ MVCC snapshot isolation
32//! - ✅ Serializable Snapshot Isolation (SSI)
33//! - ✅ Group commit for high throughput
34//! - ✅ Version chains with garbage collection
35//!
36//! ```ignore
37//! use sochdb_storage::wal_integration::MvccTransactionManager;
38//!
39//! let txm = MvccTransactionManager::new("wal.log", |key, value| {
40//! // Apply callback
41//! Ok(())
42//! })?;
43//!
44//! let txn_id = txm.begin(IsolationLevel::Serializable)?;
45//! txm.write(txn_id, b"key", b"value")?;
46//! txm.commit(txn_id)?; // fsync guarantee
47//! ```
48//!
49//! ### 2. `MvccManager` (durable_storage.rs) - SSI VALIDATION ONLY
50//!
51//! Provides SSI conflict detection but delegates durability to storage layer.
52//! Used internally by `DurableStorage` for transaction tracking.
53//!
54//! - ✅ SSI rw-antidependency detection
55//! - ✅ Bloom filter optimization for read/write sets
56//! - ❌ No WAL (relies on caller for durability)
57//!
58//! ### 3. `TransactionManager` (mvcc_snapshot.rs) - **DEPRECATED FOR NEW CODE**
59//!
60//! Minimal snapshot isolation without durability. Only suitable for:
61//! - Unit testing
62//! - Ephemeral in-memory operations
63//!
64//! **Do not use for production workloads requiring crash recovery.**
65//!
66//! ## Transaction Coordinator Trait
67//!
68//! The `TransactionCoordinator` trait unifies the common interface:
69
70use sochdb_core::Result;
71
72// Re-export TransactionMode from durable_storage (canonical definition)
73pub use crate::durable_storage::TransactionMode;
74
75/// Isolation level for transactions
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
77pub enum IsolationLevel {
78 /// Read committed - see all committed data
79 ReadCommitted,
80 /// Snapshot isolation (default) - consistent point-in-time view
81 #[default]
82 SnapshotIsolation,
83 /// Serializable via SSI - full serializability guarantee
84 Serializable,
85}
86
87/// Transaction handle returned by begin operations
88#[derive(Debug, Clone)]
89pub struct TransactionHandle {
90 /// Unique transaction ID
91 pub txn_id: u64,
92 /// Snapshot timestamp for MVCC visibility
93 pub snapshot_ts: u64,
94 /// Transaction mode
95 pub mode: TransactionMode,
96 /// Isolation level
97 pub isolation_level: IsolationLevel,
98}
99
100/// Unified transaction coordinator interface
101///
102/// This trait defines the canonical API for transaction management.
103/// All new transaction manager implementations should implement this trait.
104///
105/// ## Durability Contract
106///
107/// Implementations MUST document their durability guarantees:
108/// - `Durable`: Committed transactions survive crash (WAL + fsync)
109/// - `Ephemeral`: No durability guarantee (in-memory only)
110pub trait TransactionCoordinator: Send + Sync {
111 /// Begin a new transaction with default isolation level
112 fn begin(&self) -> Result<TransactionHandle>;
113
114 /// Begin a transaction with specified isolation level
115 fn begin_with_isolation(&self, isolation: IsolationLevel) -> Result<TransactionHandle>;
116
117 /// Begin a transaction with specified mode (for optimization)
118 fn begin_with_mode(&self, mode: TransactionMode) -> Result<TransactionHandle>;
119
120 /// Commit a transaction
121 ///
122 /// For durable implementations, this includes fsync.
123 /// Returns the commit timestamp on success.
124 fn commit(&self, txn_id: u64) -> Result<u64>;
125
126 /// Abort a transaction
127 ///
128 /// Discards all changes made by the transaction.
129 fn abort(&self, txn_id: u64) -> Result<()>;
130
131 /// Get the current snapshot timestamp for a transaction
132 fn get_snapshot_ts(&self, txn_id: u64) -> Option<u64>;
133
134 /// Check if a transaction is still active
135 fn is_active(&self, txn_id: u64) -> bool;
136
137 /// Record a read for SSI tracking
138 fn record_read(&self, txn_id: u64, key: &[u8]);
139
140 /// Record a write for SSI tracking
141 fn record_write(&self, txn_id: u64, key: &[u8]);
142
143 /// Get durability guarantee of this implementation
144 fn durability(&self) -> DurabilityLevel;
145}
146
147/// Durability guarantee level
148#[derive(Debug, Clone, Copy, PartialEq, Eq)]
149pub enum DurabilityLevel {
150 /// Fully durable with WAL + fsync
151 Durable,
152 /// Group commit (durable after batch fsync)
153 GroupCommit,
154 /// No durability (in-memory only)
155 Ephemeral,
156}
157
158/// Recovery statistics returned after crash recovery
159#[derive(Debug, Clone, Default)]
160pub struct RecoveryStats {
161 /// Number of transactions recovered
162 pub transactions_recovered: usize,
163 /// Number of individual writes recovered
164 pub writes_recovered: usize,
165 /// The commit timestamp after recovery
166 pub commit_ts: u64,
167}
168
169// =============================================================================
170// Re-exports for convenience
171// =============================================================================
172
173// Note: The canonical implementation is MvccTransactionManager from wal_integration
174// pub use crate::wal_integration::MvccTransactionManager;
175
176#[cfg(test)]
177mod tests {
178 use super::*;
179
180 #[test]
181 fn test_transaction_mode_tracking() {
182 assert!(TransactionMode::ReadWrite.tracks_reads());
183 assert!(TransactionMode::ReadWrite.tracks_writes());
184
185 assert!(!TransactionMode::ReadOnly.tracks_reads());
186 assert!(!TransactionMode::ReadOnly.tracks_writes());
187
188 assert!(!TransactionMode::WriteOnly.tracks_reads());
189 assert!(TransactionMode::WriteOnly.tracks_writes());
190 }
191
192 #[test]
193 fn test_isolation_level_default() {
194 assert_eq!(IsolationLevel::default(), IsolationLevel::SnapshotIsolation);
195 }
196}