Skip to main content

linkrs_api/api_core/
transaction_api.rs

1//! Transaction Management API - Core Layer
2//!
3//! Provides transport layer-independent transaction management capabilities
4
5use crate::api_core::{CoreError, CoreResult, SavepointId, TransactionHandle};
6use linkrs_transaction::{TransactionManager, TransactionOptions};
7use std::sync::Arc;
8
9/// Common Transaction API - Core Layer
10pub struct TransactionApi {
11    txn_manager: Arc<TransactionManager>,
12}
13
14impl TransactionApi {
15    /// Creating a New Transaction API Instance
16    pub fn new(txn_manager: Arc<TransactionManager>) -> Self {
17        Self { txn_manager }
18    }
19
20    /// Commencement of business
21    ///
22    /// # Parameters
23    /// - `options`: transaction options
24    ///
25    /// # Back
26    /// transaction handle
27    pub fn begin(&self, options: TransactionOptions) -> CoreResult<TransactionHandle> {
28        let txn_id = self
29            .txn_manager
30            .begin_transaction(options)
31            .map_err(|e| CoreError::TransactionFailed(e.to_string()))?;
32        Ok(TransactionHandle(txn_id))
33    }
34
35    /// Submission of transactions
36    ///
37    /// # Parameters
38    /// - `handle`: transaction handle
39    pub fn commit(&self, handle: TransactionHandle) -> CoreResult<()> {
40        self.txn_manager
41            .commit_transaction(handle.0)
42            .map_err(|e| CoreError::TransactionFailed(e.to_string()))
43    }
44
45    /// Rolling back (aborting) transactions
46    ///
47    /// # Parameters
48    /// `handle`: Transaction handler
49    pub fn rollback(&self, handle: TransactionHandle) -> CoreResult<()> {
50        self.txn_manager
51            .abort_transaction(handle.0)
52            .map_err(|e| CoreError::TransactionFailed(e.to_string()))
53    }
54
55    /// Get the current state of a transaction
56    ///
57    /// # Parameters
58    /// - `handle`: transaction handle
59    ///
60    /// # Return
61    /// The transaction state; an unknown handle is a caller error rather
62    /// than a synthetic "Unknown" state.
63    pub fn get_status(
64        &self,
65        handle: TransactionHandle,
66    ) -> CoreResult<linkrs_transaction::TransactionState> {
67        self.txn_manager
68            .get_transaction_info(handle.0)
69            .map(|info| info.state)
70            .ok_or_else(|| {
71                CoreError::NotFound(format!("Transaction {} does not exist", handle.id()))
72            })
73    }
74
75    /// Check if a transaction exists and is active
76    ///
77    /// # Parameters
78    /// - `handle`: transaction handle
79    pub fn is_active(&self, handle: TransactionHandle) -> bool {
80        self.txn_manager.is_transaction_active(handle.0)
81    }
82
83    /// Get the number of active transactions
84    pub fn active_count(&self) -> usize {
85        self.txn_manager.list_active_transactions().len()
86    }
87
88    /// Create a savepoint within a transaction
89    ///
90    /// # Parameters
91    /// - `handle`: transaction handle
92    /// - `name`: optional savepoint name
93    /// - `staged_mark`: storage-staged write boundary peeked from the undo
94    ///   target before this call (`None` when the target holds no staged
95    ///   writes)
96    ///
97    /// # Returns
98    /// Savepoint ID on success
99    pub fn create_savepoint(
100        &self,
101        handle: TransactionHandle,
102        name: Option<String>,
103        staged_mark: Option<linkrs_storage::StagedWriteMark>,
104    ) -> CoreResult<SavepointId> {
105        self.txn_manager
106            .create_savepoint(handle.0, name, staged_mark)
107            .map_err(|e| CoreError::TransactionFailed(e.to_string()))
108            .map(SavepointId)
109    }
110
111    /// Rollback to a savepoint
112    ///
113    /// # Parameters
114    /// - `handle`: transaction handle
115    /// - `savepoint_id`: savepoint ID to rollback to
116    /// - `storage`: reference to storage for undo operations
117    pub fn rollback_to_savepoint(
118        &self,
119        handle: TransactionHandle,
120        savepoint_id: SavepointId,
121        storage: &impl linkrs_storage::UndoTarget,
122    ) -> CoreResult<()> {
123        self.txn_manager
124            .rollback_to_savepoint(handle.0, savepoint_id.0, storage)
125            .map_err(|e| CoreError::TransactionFailed(e.to_string()))
126    }
127
128    /// Release a savepoint
129    ///
130    /// # Parameters
131    /// - `handle`: transaction handle
132    /// - `savepoint_id`: savepoint ID to release
133    pub fn release_savepoint(
134        &self,
135        handle: TransactionHandle,
136        savepoint_id: SavepointId,
137    ) -> CoreResult<()> {
138        let context = self
139            .txn_manager
140            .get_context(handle.0)
141            .map_err(|e| CoreError::TransactionFailed(e.to_string()))?;
142        context
143            .release_savepoint(savepoint_id.0)
144            .map_err(|e| CoreError::TransactionFailed(e.to_string()))?;
145        Ok(())
146    }
147
148    /// Get all savepoints for a transaction
149    ///
150    /// # Parameters
151    /// - `handle`: transaction handle
152    pub fn get_savepoints(
153        &self,
154        handle: TransactionHandle,
155    ) -> CoreResult<Vec<linkrs_transaction::SavepointInfo>> {
156        let context = self
157            .txn_manager
158            .get_context(handle.0)
159            .map_err(|e| CoreError::TransactionFailed(e.to_string()))?;
160        Ok(context.get_all_savepoints())
161    }
162}
163
164impl Clone for TransactionApi {
165    fn clone(&self) -> Self {
166        Self {
167            txn_manager: Arc::clone(&self.txn_manager),
168        }
169    }
170}