runInTransaction<T> method

T runInTransaction<T>(
  1. T body()
)

Runs body inside a single transaction. Re-entrant: a nested call joins the outer transaction rather than starting its own, and a rollback anywhere aborts the whole outermost transaction. On any thrown error the (outermost) transaction rolls back and the error propagates.

Implementation

T runInTransaction<T>(T Function() body) {
  if (_txnDepth > 0) {
    // Already inside a transaction — join it. A throw here sets the
    // rollback flag so the outermost frame rolls the whole thing back.
    try {
      return body();
    } catch (_) {
      _rollbackPending = true;
      rethrow;
    }
  }
  _db.execute('BEGIN IMMEDIATE;');
  _txnDepth++;
  _rollbackPending = false;
  try {
    final result = body();
    if (_rollbackPending) {
      _db.execute('ROLLBACK;');
    } else {
      _db.execute('COMMIT;');
    }
    return result;
  } catch (_) {
    _db.execute('ROLLBACK;');
    rethrow;
  } finally {
    _txnDepth--;
    _rollbackPending = false;
  }
}