Skip to content

Commit

Permalink
Make database init / update transactional (#279)
Browse files Browse the repository at this point in the history
* Make database init / update transactional

That is, run both schema modifications as well as init/update reducers
in the same transaction.

* Add commentary
  • Loading branch information
kim authored Sep 12, 2023
1 parent 32ac808 commit 8f23b6a
Show file tree
Hide file tree
Showing 2 changed files with 241 additions and 125 deletions.
30 changes: 30 additions & 0 deletions crates/core/src/db/relational_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,21 @@ impl RelationalDB {
self.finish_tx(tx, res)
}

/// Run a fallible function in a transaction, rolling it back if the
/// function returns `Err`.
///
/// Similar in purpose to [`Self::with_auto_commit`], but returns the
/// [`MutTxId`] alongside the `Ok` result of the function `F` without
/// committing the transaction.
pub fn with_auto_rollback<F, A, E>(&self, mut tx: MutTxId, f: F) -> Result<(MutTxId, A), E>
where
F: FnOnce(&mut MutTxId) -> Result<A, E>,
E: From<DBError>,
{
let res = f(&mut tx);
self.rollback_on_err(tx, res)
}

/// Perform the transactional logic for the `tx` according to the `res`
pub fn finish_tx<A, E>(&self, tx: MutTxId, res: Result<A, E>) -> Result<A, E>
where
Expand All @@ -302,6 +317,21 @@ impl RelationalDB {
}
res
}

/// Roll back transaction `tx` if `res` is `Err`, otherwise return it
/// alongside the `Ok` value.
pub fn rollback_on_err<A, E>(&self, tx: MutTxId, res: Result<A, E>) -> Result<(MutTxId, A), E>
where
E: From<DBError>,
{
match res {
Err(e) => {
self.rollback_tx(tx);
Err(e)
}
Ok(a) => Ok((tx, a)),
}
}
}

impl RelationalDB {
Expand Down
Loading

1 comment on commit 8f23b6a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark for 8f23b6a

Click to view benchmark
Test Base PR %
empty reducer 23.8±0.56µs 26.0±1.43µs +9.24%
filter nonunique random/100 36.8±2.71µs 37.0±1.55µs +0.54%
filter nonunique random/1000 37.2±1.90µs 38.3±2.47µs +2.96%
filter nonunique random/10000 37.4±1.90µs 36.5±2.03µs -2.41%
filter nonunique sequential/100 36.8±2.14µs 39.1±3.43µs +6.25%
filter nonunique sequential/1000 38.6±1.87µs 36.3±2.97µs -5.96%
filter nonunique sequential/10000 37.7±1.83µs 38.9±2.74µs +3.18%
filter nonunique sequential/100000 39.7±2.85µs 38.3±2.27µs -3.53%
filter unique random/100 32.9±1.72µs 32.7±3.46µs -0.61%
filter unique random/1000 34.1±1.78µs 33.1±2.50µs -2.93%
filter unique random/10000 34.1±4.85µs 33.3±2.67µs -2.35%
filter unique sequential/100 32.9±1.77µs 34.3±2.58µs +4.26%
filter unique sequential/1000 35.6±1.79µs 34.5±2.42µs -3.09%
filter unique sequential/10000 35.8±2.67µs 33.7±1.55µs -5.87%
filter unique sequential/100000 35.0±2.54µs 32.6±1.27µs -6.86%
iterator/1_000_000 rows 535.0±2.60ms 586.6±3.82ms +9.64%
large input 1300.1±197.24µs 1328.5±253.55µs +2.18%
multi insert/10 65.3±3.88µs 68.1±8.41µs +4.29%
multi insert/100 310.5±6.52µs 326.4±18.66µs +5.12%
multi insert/1000 2.9±0.03ms 2.9±0.03ms 0.00%
multi insert/50 166.3±4.09µs 168.6±3.41µs +1.38%
multi insert/500 1431.7±24.41µs 1468.8±32.09µs +2.59%
multiple large arguments 12.7±0.15ms 12.1±0.20ms -4.72%
single insert 51.9±3.75µs 52.0±4.87µs +0.19%
with existing records/100000 50.1±7.25µs 53.7±3.86µs +7.19%
with existing records/1000000 60.1±5.57µs 57.0±5.38µs -5.16%
with existing records/200000 56.4±4.19µs 56.3±5.92µs -0.18%
with existing records/300000 55.9±4.31µs 53.2±5.10µs -4.83%
with existing records/400000 60.7±6.15µs 56.7±4.86µs -6.59%
with existing records/500000 59.1±6.42µs 59.4±3.80µs +0.51%
with existing records/600000 59.5±3.32µs 59.8±4.77µs +0.50%
with existing records/700000 57.8±4.92µs 58.5±4.16µs +1.21%
with existing records/800000 61.8±6.98µs 59.9±5.74µs -3.07%
with existing records/900000 62.5±6.84µs 60.3±5.27µs -3.52%

Please sign in to comment.