runInTransaction<R> method

R runInTransaction<R>(
  1. TxMode mode,
  2. R fn()
)

Executes a given function inside a transaction. Returns fn's result. Aborts a transaction and rethrows on exception if fn is asynchronous.

A transaction can group several operations into a single unit of work that either executes completely or not at all. The advantage of explicit transactions over the bulk put operations is that you can perform any number of operations and use objects of multiple boxes. In addition, you get a consistent (transactional) view on your data while the transaction is in progress.

Implementation

@pragma('vm:prefer-inline')
R runInTransaction<R>(TxMode mode, R Function() fn) {
  // Whether the function is an `async` function. We can't allow those because
  // the isolate could be transferred to another thread during execution.
  // Checking the return value seems like the only thing we can in Dart v2.12.
  if (fn is Future Function()) {
    // This is a special case when the given function always throws. Triggered
    //  in our test code. No need to even start a DB transaction in that case.
    if (fn is Never Function()) {
      // WARNING: don't be tempted to just `return fn();` - the code may
      // execute DB operations which wouldn't be rolled back after the throw.
      throw UnsupportedError('Given transaction callback always fails.');
    }
    throw UnsupportedError(
        'Executing an "async" function in a transaction is not allowed.');
  }

  return _runInTransaction(mode, (tx) => fn());
}