runWithBegin<T> static method

Future<T> runWithBegin<T>(
  1. TransactionHandle? beginFn(),
  2. Future<T> action(
    1. TransactionHandle txn
    )
)

Runs action inside a fresh transaction obtained from beginFn.

On normal completion the transaction is committed; on any thrown exception (or runtime error) it is rolled back before rethrowing. This mirrors Transaction::execute on the Rust side and is the easiest way to write leak-proof Dart transaction code.

beginFn is whatever piece of API returns a TransactionHandle? (e.g. NativeOdbcConnection.beginTransactionHandle).

Implementation

static Future<T> runWithBegin<T>(
  TransactionHandle? Function() beginFn,
  Future<T> Function(TransactionHandle txn) action,
) async {
  final txn = beginFn();
  if (txn == null) {
    throw StateError('beginTransactionHandle returned null');
  }
  try {
    final result = await action(txn);
    txn.commit();
    return result;
  } on Object {
    if (txn.isActive) {
      txn.rollback();
    }
    rethrow;
  }
}