Транзакция в Rust
Транзакция объединяет несколько изменений:
до подтверждения они видны только внутри
соединения, а после commit попадают
в файл целиком. При сбое можно не
подтверждать, и файл останется в старом
состоянии.
Откроем транзакцию, вставим две строки и подтвердим:
use rusqlite::{Connection, params};
fn seed_pair() -> Result<(), rusqlite::Error> {
let mut conn = Connection::open("app.db")?;
let tx = conn.transaction()?;
tx.execute(
"INSERT INTO user (id, name) VALUES (?1, ?2)",
params![1, "ann"],
)?;
tx.execute(
"INSERT INTO user (id, name) VALUES (?1, ?2)",
params![2, "bob"],
)?;
tx.commit()?;
Ok(())
}
fn main() {
match seed_pair() {
Ok(()) => println!("commit"),
Err(e) => println!("{}", e),
}
}
На экране commit. Обе строки
появляются в файле только после
подтверждения.
Без подтверждения изменения исчезнут
при закрытии транзакции. Альтернатива
transaction - неявная транзакция
на одно изменение, но для пары шагов
удобнее явный блок:
use rusqlite::{Connection, params};
fn move_name() -> Result<(), rusqlite::Error> {
let mut conn = Connection::open("app.db")?;
let tx = conn.transaction()?;
tx.execute(
"UPDATE user SET name = ?1 WHERE id = ?2",
params!["amy", 1],
)?;
tx.execute(
"DELETE FROM user WHERE id = ?1",
params![2],
)?;
tx.commit()?;
Ok(())
}
fn main() {
if let Err(e) = move_name() {
println!("{}", e);
}
}
Дана таблица:
CREATE TABLE user (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
В одной транзакции добавьте строки
1 ann и 2 bob,
подтвердите и выведите pair.
Дана таблица с одной строкой 1
ann. В транзакции измените имя
и сразу прочитайте его до commit,
затем подтвердите.
Скажите, что произойдет с незакрепленными
изменениями, если транзакцию уничтожить
без commit.