transaction<T> method
Runs the provided non-async function inside a transaction.
The function may not use async/await otherwise the transaction may commit before the queries are actually executed. This is a limitation of some adapters, that the function passed to the transaction runs "synchronously" through callbacks without releasing the event loop.
Implementation
@override
Future<T> transaction<T>(
void Function(Transaction tx, void Function(T res) setResult) f,
) {
return txLock.synchronized(() async {
db.execute('BEGIN');
try {
final txCompleter = Completer<T>();
final tx = Transaction(this, (e) => txCompleter.completeError(e));
runZonedGuarded(() {
f(tx, (T res) {
// Commit the transaction when the user sets the result.
// This assumes that the user does not execute any more queries after setting the result.
db.execute('COMMIT');
txCompleter.complete(res);
});
}, (error, stack) {
txCompleter.completeError(error);
});
return await txCompleter.future;
} catch (e) {
db.execute('ROLLBACK');
rethrow;
}
});
}