internal async Task <IReadOnlyList <long> > ExecuteNonQueryWithRetryAsync(SpannerRetriableBatchCommand command, CancellationToken cancellationToken = default) { while (true) { var spannerCommand = command.CreateSpannerBatchCommand(); try { IReadOnlyList <long> res = await spannerCommand.ExecuteNonQueryAsync(cancellationToken); _retriableStatements.Add(new RetriableBatchDmlStatement(command, res)); return(res); } catch (SpannerException e) when(e.ErrorCode == ErrorCode.Aborted) { await RetryAsync(e, cancellationToken); } catch (SpannerException e) { _retriableStatements.Add(new FailedBatchDmlStatement(command, e)); throw; } } }
/// <summary> /// Executes a <see cref="SpannerBatchCommand"/> and retries the entire transaction if the /// command fails with an Aborted error. /// </summary> /// <param name="command">The command to execute. Must be a batch of DML statements.</param> /// <returns>The number of affected rows per statement.</returns> protected internal abstract IReadOnlyList <long> ExecuteNonQueryWithRetry(SpannerRetriableBatchCommand command);
protected internal override IReadOnlyList <long> ExecuteNonQueryWithRetry(SpannerRetriableBatchCommand command) => Task.Run(() => ExecuteNonQueryWithRetryAsync(command, CancellationToken.None)).ResultWithUnwrappedExceptions();
internal RetriableBatchDmlStatement(SpannerRetriableBatchCommand command, IReadOnlyList <long> updateCounts) { // TODO: Do we need to make this a clone? _command = command; _updateCounts = updateCounts; }
internal FailedBatchDmlStatement(SpannerRetriableBatchCommand command, SpannerException exception) { _command = command; _exception = exception; }
/// <summary> /// Read-only transactions cannot execute non-query statements. Calling this method will throw an <see cref="InvalidOperationException"/>. /// </summary> /// <exception cref="InvalidOperationException"></exception> protected internal override IReadOnlyList <long> ExecuteNonQueryWithRetry(SpannerRetriableBatchCommand command) => throw new InvalidOperationException("Non-query operations are not allowed on a read-only transaction");