sqlite
sqlite copied to clipboard
Introduce transaction and savepoint objects
Hello, would you be willing to include transaction and savepoints? The structures here will automatically rollback when dropped.
Thanks for the package and for considering this addition!
Thank you for the pull request! I am not sure if this is needed, as it can be achieved via queries.
Hello, thanks for considering.
I admit, it is not strictly necessary, but the logic for rollback gets ugly without something that does a rollback on Drop. In particular, using the ?
shorthand pretty much needs something scope-protected.
Example:
fn do_something(connection: Connection) -> Result<(), Error> {
let mut txn = connection.begin()?;
connection.execute(...)?; // On Err(), ROLLBACK called automatically
connection.execute(...)?;
connection.execute(...)?;
txn.commit()?;
}
Compared to some construction like one of these:
fn do_something(connection: Connection) -> Result<(), Error> {
connection.execute("BEGIN")?;
if let Ok(_) = connection.execute(...) {
if let Ok(_) = connection.execute(...) {
if let Ok(_) = connection.execute(...) {
if let Ok(_) = connection.execute("COMMIT") {
return Ok(());
}
}
}
}
connection.execute("ROLLBACK")?;
return Err(...);
}
fn do_something(connection: Connection) -> Result<(), Error> {
connection.execute("BEGIN")?;
if let Err(e) = connection.execute(...) {
connection.execute("ROLLBACK")?;
return Err(...);
}
if let Err(e) = connection.execute(...) {
connection.execute("ROLLBACK")?;
return Err(...);
}
if let Err(e) = connection.execute(...) {
connection.execute("ROLLBACK")?;
return Err(...);
}
if let Err(e) = connection.execute("COMMIT") {
connection.execute("ROLLBACK")?;
return Err(...);
}
return Ok(());
}
fn do_something(connection: Connection) -> Result<(), Error> {
connection.execute("BEGIN")?;
let mut res = _really_do_something(connection);
if res.is_ok() {
res = connection.execute("COMMIT");
}
if res.is_err() {
connection.execute("ROLLBACK")?;
return res;
}
return Ok(());
}
fn _really_do_something(connection: Connection) -> Result<(), Error> {
connection.execute(...)?;
connection.execute(...)?;
connection.execute(...)?;
}
I do notice that I should have added more tests than just the documentation test. If this is something you'd like, I'm happy to write some tests for it.
Thank you for the PR! I am closing this.
This was not merged, right? What's the supported approach for handling transactions?