Транзакция SQLite в Dart
По умолчанию SQLite фиксирует каждый запрос отдельно.
Команды BEGIN, COMMIT и ROLLBACK
складывают шаги в одну транзакцию до явной фиксации
или отката.
Два успешных INSERT попадут на диск только
после COMMIT:
import 'package:sqlite3/sqlite3.dart';
var db = sqlite3.open('txn_ok.db');
db.execute('''
CREATE TABLE IF NOT EXISTS moves (
id INTEGER PRIMARY KEY,
step TEXT NOT NULL
)
''');
db.execute('BEGIN');
try {
db.execute(
'INSERT INTO moves (step) VALUES (?)',
['load'],
);
db.execute(
'INSERT INTO moves (step) VALUES (?)',
['seal'],
);
db.execute('COMMIT');
} on Object catch (_) {
db.execute('ROLLBACK');
rethrow;
}
db.dispose();
При ошибке между шагами ROLLBACK отменяет
несохраненные изменения в рамках транзакции:
import 'package:sqlite3/sqlite3.dart';
var db = sqlite3.open('txn_fail.db');
db.execute('''
CREATE TABLE IF NOT EXISTS moves (
id INTEGER PRIMARY KEY,
step TEXT NOT NULL
)
''');
db.execute('BEGIN');
try {
db.execute(
'INSERT INTO moves (step) VALUES (?)',
['start'],
);
throw StateError('stop');
} on Object catch (_) {
db.execute('ROLLBACK');
}
var rows = db.select('SELECT COUNT(*) AS c FROM moves');
if (rows.isNotEmpty) {
print(rows.first['c']);
}
db.dispose();
Создайте таблицу ledger_tx в bank.db
с полем note, выполните два добавления
в одной транзакции и зафиксируйте их.
Повторите два добавления, но вызовите откат перед
фиксацией и выведите 0 строк в таблице.