/// <inheritdoc />
 public async ValueTask RollbackAsync(CancellationToken cancellationToken = default)
 {
     try {
         await npgsqlTransaction.RollbackAsync(cancellationToken);
     }
     catch (Exception ex) {
         NpgsqlExceptions.Handle(ex);
         throw;
     }
 }
        async ValueTask <TTransaction> DoBegin <TTrait, TTransaction>
            (IsolationLevel isolationLevel,
            CancellationToken cancellationToken,
            SqlAccess?access,
            Int32?defaultQueryTimeout,
            Int32 retry = 0)
            where TTrait : struct, IBeginTrait <TTransaction>
            where TTransaction : ISqlTransaction
        {
            while (true)
            {
                var npgsqlConnection = new NpgsqlConnection(connectionString);
                try {
                    await npgsqlConnection.OpenAsync(cancellationToken);

                    var npgsqlTransaction =
                        await npgsqlConnection.BeginTransactionAsync(isolationLevel, cancellationToken);

                    var transaction =
                        default(TTrait).CreateTransaction(
                            npgsqlConnection,
                            npgsqlTransaction,
                            isolationLevel,
                            access ?? settings.defaultAccess,
                            defaultQueryTimeout ?? settings.defaultQueryTimeout);

                    if (access is { } accessValue&& accessValue != settings.defaultAccess)
                    {
                        await transaction.SetAccessAsync(accessValue, cancellationToken);
                    }

                    npgsqlConnection = null;
                    return(transaction);
                }
                catch (NpgsqlException ex) when(ex.IsTransient)
                {
                    if (++retry < beginRetryDelays.Length)
                    {
                        var timestamp = Environment.TickCount64;

                        await(npgsqlConnection?.DisposeAsync() ?? default);
                        npgsqlConnection = null;

                        var delay = beginRetryDelays[retry] - (Int32)(Environment.TickCount64 - timestamp);
                        if (delay > 0)
                        {
                            await Task.Delay(delay, cancellationToken);
                        }
                        else
                        {
                            await Task.Yield();
                        }
                    }
                    else
                    {
                        throw NpgsqlExceptions.MatchToSqlException(ex) !;
                    }
                }
                catch (Exception ex) when(NpgsqlExceptions.MatchToSqlException(ex) is { } sqlEx)
                {
                    throw sqlEx;
                }