transaction<T> method

Future<T> transaction<T>(
  1. Future<T> body(
    1. Transaction tx
    )
)

Runs body inside a database transaction.

final count = await db.transaction((tx) async {
  await tx.execute('INSERT INTO users(name) VALUES (?)', ['Ada']);
  final rows = await tx.select('SELECT COUNT(*) as c FROM users');
  return rows.first['c'] as int;
});

All operations within body are applied atomically. If body completes normally, the transaction commits. If body throws, the transaction rolls back and the exception is rethrown.

The Transaction passed to body supports both Transaction.execute and Transaction.select. Reads inside the transaction see uncommitted writes from earlier statements in the same transaction.

Stream invalidation happens once on commit, not per statement. Rolled-back transactions do not trigger stream re-queries.

Returns the value returned by body.

Implementation

Future<T> transaction<T>(Future<T> Function(Transaction tx) body) async {
  final transaction = Transaction.current;
  if (transaction != null) {
    return transaction.transaction(body);
  }

  _ensureOpen();

  final writer = await _writer;
  return writer.locked(() => writer.transaction(body));
}