access<T> function

Future<T> access<T>(
  1. FutureOr<T> command(
    1. DBAccess access
    )
)

Executes a command within a transaction.

access((DBAccess access) async { await for (final row in await access.query('select ...')) { ... } ... await access.execute('update...'); }); //The transaction ends here. It commits if success, //Or, rolls back if an exception is thrown or DBAccess.rollingback //is set to a value other than false and null.

It returns what was returned by command.

Implementation

Future<T> access<T>(FutureOr<T> command(DBAccess access)) async {
  Object? error;
  bool closing = false;
  DBAccess? access;

  ++_nAccess;
  try {
    onAccess?.call(command, _nAccess);

    access = DBAccess._(await _pool!.connect());
    await access._begin();

    final result = await command(access);

    closing = true;
    if (!access._closed)
      if (access.rollingback == false) {
        await access._commit();
      } else {
        error = access.rollingback; //yes, use it as an error
        await access._rollback();
      }

    return result;

  } catch (ex) {
    error = ex;
    if (access != null && !access._closed && !closing)
      await InvokeUtil.invokeSafely(access._rollback);
    rethrow;

  } finally {
    if (access != null && !access._closed)
      access._close(error); //never throws an exception
    --_nAccess;
  }
}