Class ProjectionTransactionExtensions
- Namespace
- Stratara.Projections
- Assembly
- Stratara.Projections.dll
Helpers for the write half of an idempotent projection.
public static class ProjectionTransactionExtensions
- Inheritance
-
ProjectionTransactionExtensions
- Inherited Members
Remarks
At-least-once delivery means a projection will see the same event twice, and cascading deletes mean a row can vanish between the read and the write. Neither is a fault. A second writer changing a row that still exists is, and it must keep stopping the bundle.
The other half of writing an idempotent projection needs no helper: load the row, and return when it is not there.
var tenant = await repository.GetAsync(@event.StreamId, cancellationToken);
if (tenant is null) { return; }
Methods
SaveChangesIdempotentAsync(ITransaction, Func<CancellationToken, Task<bool>>, CancellationToken)
Commits the transaction, treating a concurrency conflict as satisfied when the row the write targeted is gone — a concurrent bundle reached the same end state first.
public static Task<int> SaveChangesIdempotentAsync(this ITransaction transaction, Func<CancellationToken, Task<bool>> targetStillExists, CancellationToken cancellationToken = default)
Parameters
transactionITransactionThe active read transaction.
targetStillExistsFunc<CancellationToken, Task<bool>>Probes whether the write's target is still present. Evaluated only after a conflict. Return true if any targeted row still exists, which makes the conflict a real one.
cancellationTokenCancellationTokenA token to cancel the operation.
Returns
Exceptions
- ConcurrencyConflictException
Rethrown when
targetStillExistsreports the row is still there. Suppressing it would turn "a failing projection stops the bundle" into a guarantee that holds only where nobody used this helper.