quill_sql/transaction/
runtime.rs1use crate::error::{QuillSQLError, QuillSQLResult};
2use crate::storage::page::TupleMeta;
3use crate::transaction::{
4 IsolationLevel, LockMode, Transaction, TransactionManager, TransactionSnapshot,
5};
6use crate::utils::table_ref::TableReference;
7
8use crate::storage::page::RecordId;
9
10pub struct TxnRuntime<'a> {
14 txn: &'a mut Transaction,
15 manager: &'a TransactionManager,
16 snapshot: TransactionSnapshot,
17 command_id: crate::transaction::CommandId,
18}
19
20impl<'a> TxnRuntime<'a> {
21 pub fn new(manager: &'a TransactionManager, txn: &'a mut Transaction) -> Self {
22 let command_id = txn.begin_command();
23 let snapshot = match txn.isolation_level() {
24 IsolationLevel::RepeatableRead | IsolationLevel::Serializable => {
25 if let Some(existing) = txn.snapshot().cloned() {
26 existing
27 } else {
28 let snap = manager.snapshot(txn.id());
29 txn.set_snapshot(snap.clone());
30 snap
31 }
32 }
33 IsolationLevel::ReadCommitted | IsolationLevel::ReadUncommitted => {
34 let snap = manager.snapshot(txn.id());
35 txn.clear_snapshot();
36 snap
37 }
38 };
39 Self {
40 txn,
41 manager,
42 snapshot,
43 command_id,
44 }
45 }
46
47 pub fn id(&self) -> crate::transaction::TransactionId {
48 self.txn.id()
49 }
50
51 pub fn command_id(&self) -> crate::transaction::CommandId {
52 self.command_id
53 }
54
55 pub fn snapshot(&self) -> &TransactionSnapshot {
56 &self.snapshot
57 }
58
59 pub fn transaction(&self) -> &Transaction {
60 self.txn
61 }
62
63 pub fn transaction_mut(&mut self) -> &mut Transaction {
64 self.txn
65 }
66
67 pub fn manager(&self) -> &TransactionManager {
68 self.manager
69 }
70
71 pub fn is_visible(&self, meta: &TupleMeta) -> bool {
72 self.snapshot.is_visible(meta, self.command_id, |txn_id| {
73 self.manager.transaction_status(txn_id)
74 })
75 }
76
77 pub fn lock_table(&self, table: TableReference, mode: LockMode) -> QuillSQLResult<()> {
78 self.manager
79 .acquire_table_lock(self.txn, table.clone(), mode)
80 .map_err(|e| QuillSQLError::Execution(format!("lock error: {}", e)))
81 }
82
83 pub fn try_lock_row(
84 &self,
85 table: TableReference,
86 rid: RecordId,
87 mode: LockMode,
88 ) -> QuillSQLResult<bool> {
89 self.manager
90 .try_acquire_row_lock(self.txn, table, rid, mode)
91 }
92
93 pub fn record_shared_row_lock(&self, table: TableReference, rid: RecordId) {
94 self.manager
95 .record_shared_row_lock(self.txn.id(), table, rid);
96 }
97
98 pub fn remove_row_key_marker(&self, table: &TableReference, rid: RecordId) {
99 self.manager
100 .remove_row_key_marker(self.txn.id(), table, rid);
101 }
102
103 pub fn try_unlock_shared_row(
104 &self,
105 table: &TableReference,
106 rid: RecordId,
107 ) -> QuillSQLResult<()> {
108 self.manager
109 .try_unlock_shared_row(self.txn.id(), table, rid)
110 }
111
112 pub fn unlock_row(&self, table: &TableReference, rid: RecordId) {
113 self.manager.unlock_row(self.txn.id(), table, rid);
114 }
115}