small_db/
transaction.rs

1use core::fmt;
2use std::sync::atomic::{AtomicU64, Ordering};
3
4use crate::{
5    btree::page_cache::PageCache, types::SmallResult, Unique,
6};
7
8static TRANSACTION_ID: AtomicU64 = AtomicU64::new(1);
9
10#[derive(Eq, Hash, PartialEq, Clone, Copy)]
11pub struct Transaction {
12    // increase monotonically by 1
13    uuid: u64,
14}
15
16impl Transaction {
17    pub fn new() -> Self {
18        Self {
19            uuid: TRANSACTION_ID.fetch_add(1, Ordering::Relaxed),
20        }
21    }
22
23    pub fn start(&self) -> SmallResult {
24        Unique::mut_log_manager().log_start(self)
25    }
26
27    pub fn commit(&self) -> SmallResult {
28        self.complete(true, &Unique::mut_page_cache())
29    }
30
31    pub fn manual_commit(
32        &self,
33        page_cache: &PageCache,
34    ) -> SmallResult {
35        self.complete(true, page_cache)
36    }
37
38    pub fn abort(&self) -> SmallResult {
39        self.complete(false, &Unique::mut_page_cache())
40    }
41
42    pub fn manual_abort(
43        &self,
44        page_cache: &PageCache,
45    ) -> SmallResult {
46        self.complete(false, page_cache)
47    }
48
49    fn complete(
50        &self,
51        commit: bool,
52        page_cache: &PageCache,
53    ) -> SmallResult {
54        // write abort log record and rollback transaction
55        if !commit {
56            // does rollback too
57            Unique::mut_log_manager().log_abort(self, page_cache)?;
58        }
59
60        // Release locks and flush pages if needed
61        //
62        // release locks
63        page_cache.tx_complete(self, commit);
64
65        // write commit log record
66        if commit {
67            Unique::mut_log_manager().log_commit(self)?;
68        }
69
70        Unique::concurrent_status().release_lock_by_tx(self)?;
71
72        Ok(())
73    }
74
75    pub fn get_id(&self) -> u64 {
76        self.uuid
77    }
78}
79
80// This function will led to a bug:
81// thread 'main' panicked at 'rwlock write lock would result in
82// deadlock', /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/
83// std/src/sys/unix/ locks/pthread_rwlock.rs:111:13 impl Drop for
84// Transaction {     fn drop(&mut self) {
85//         self.commit().unwrap();
86//     }
87// }
88
89impl fmt::Display for Transaction {
90    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91        write!(f, "tx_{}", self.uuid)
92    }
93}
94
95impl fmt::Debug for Transaction {
96    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97        return write!(f, "{}", self);
98    }
99}