Struct BatchWriteCommand<T>
- Namespace
- DynaSharp
- Assembly
- DynaSharp.dll
A BatchWriteItem under construction: puts and deletes of any number, also of other types and other tables in the same batch, as in
shop.BatchWrite().Put(item).Delete(pk, sk).Put(orders, order). It is not atomic, runs in requests of 25 writes, sends again what DynamoDB left unprocessed, and gives up with a
BatchIncompleteException. Chain the writes and end with SendAsync(CancellationToken) in one expression.
public readonly ref struct BatchWriteCommand<T> : IRetryable<BatchWriteCommand<T>> where T : IDynamoDbDocument<T>
Type Parameters
TThe type of the table the batch was started on.
- Implements
- Inherited Members
Examples
var written = await products.BatchWrite().PutAll(catalog).SendAsync(ct);
Remarks
Not atomic. Each write succeeds or fails on its own, and when the batch ends early the writes before that stay applied. A batch has no conditions and no update either: what needs those is a TransactWriteCommand, and costs twice the capacity.
Requests of 25 writes. DynamoDB takes 25 writes and 16 MB in a request, and an item can have 400 KB. The command cuts the batch into requests that fit, which run one after the other.
Unprocessed writes go out again. That happens after a backoff with jitter on TimeProvider. A retry repeats a put or a delete, which is safe: the item ends up as it was written.
It gives up after 8 requests in a row that get nothing done, or as many as MaxStalledRounds(int) says, with a BatchIncompleteException that holds what was not written. A round that writes something does not count against that. Any other failure after a request went through ends the batch the same way, with the failure as its InnerException, and so does a timeout, a lost connection or a server error of the first request. The writes of a request that got no answer count as not written, though DynamoDB may have applied some of them; sending them again is safe. Any other failure of the first request surfaces as it is, and a cancellation stays an OperationCanceledException, which reports no progress.
A key twice. DynamoDB rejects a request that holds one key twice with a ValidationException, and the command does not look for duplicates: an item can hold its key anywhere, and a write costs no read of it here. So a key that occurs twice in one request fails that request, with the requests before it applied and reported, and one that occurs in two requests is written twice, in order.
Telemetry has one span per request, so a batch can make several, and they carry the tables and the capacity of their own request. See GetCommand<T> for what a command is and what it cannot do.
Methods
Delete(Table<Item>, AttributeValue, AttributeValue)
Adds a delete on another table, one without a schema, by the values of the key. A table of an entity takes a generated key instead.
public BatchWriteCommand<T> Delete(Table<Item> table, AttributeValue partitionKey, AttributeValue sortKey = default)
Parameters
tableTable<Item>The table.
partitionKeyAttributeValueThe partition key as it is stored. Strings and binary values must not be empty.
sortKeyAttributeValueThe sort key as it is stored, which a table with a sort key needs.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Exceptions
- ArgumentNullException
tableis null.- ArgumentException
A key is empty, or the table has no sort key.
DeleteAll<TKey>(IEnumerable<TKey>)
Adds a delete of each generated key, any number of them, which SendAsync(CancellationToken) sends in requests of 25 writes. Deleting what does not exist is no error. The keys are written here and now, so the sequence is enumerated once, before
anything is sent. It takes a sequence of a generated key, such as ids.Select(Order.Keys.Of), and an IEnumerable<T> of IKey<TEntity>.
public BatchWriteCommand<T> DeleteAll<TKey>(IEnumerable<TKey> keys) where TKey : IKey<T>
Parameters
keysIEnumerable<TKey>The keys.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Type Parameters
TKeyThe key. A key of another entity is a compile error.
Exceptions
- ArgumentNullException
keysor one of them is null.
Delete<TKey>(TKey)
Adds a delete by a generated key. Deleting what does not exist is no error.
public BatchWriteCommand<T> Delete<TKey>(TKey key) where TKey : IKey<T>
Parameters
keyTKeyThe key.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Type Parameters
TKeyThe key. A key of another entity is a compile error.
Exceptions
- ArgumentNullException
keyis null.
Delete<TOther, TKey>(Table<TOther>, TKey)
Adds a delete by a generated key on another table.
public BatchWriteCommand<T> Delete<TOther, TKey>(Table<TOther> table, TKey key) where TOther : IDynamoDbDocument<TOther> where TKey : IKey<TOther>
Parameters
tableTable<TOther>The table.
keyTKeyThe key.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Type Parameters
TOtherThe type of the table.
TKeyThe key. A key of another entity is a compile error.
Exceptions
- ArgumentNullException
tableorkeyis null.
IgnoreVersion()
Lets the batch write entities with a VersionAttribute as they are: a batch cannot carry a condition, so without this SendAsync(CancellationToken) throws InvalidOperationException for such an entity.
public BatchWriteCommand<T> IgnoreVersion()
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Remarks
The whole batch. It holds for every write of the batch, wherever in the chain it stands. The version of what the batch writes is not checked, and each item is stored with the version of its entity plus one, as a put stores it, so an entity at 0 is stored at 1.
The version still advances. Every write of a versioned entity stores a new version, also one without the check: an update adds 1 to the stored version,
SET #v = if_not_exists(#v, :zero) + :one, so an item without one, or a new item, gets version 1, and a put or a batch stores the version of its entity plus one, as a checked put does. A writer
that holds a copy read before this write then fails with ConditionalCheckFailedException, or in a transaction with TransactionCanceledException, instead of overwriting it.
What this write itself overwrites is not checked: it wins over whatever another writer stored since, so it suits a change that does not depend on what was read, such as an Add to a counter.
MaxAttempts(int)
Sets the number of attempts of each request including the first, in place of MaxAttempts. It is about one request and says nothing about writes that come back unprocessed, which MaxStalledRounds(int) bounds.
public BatchWriteCommand<T> MaxAttempts(int attempts)
Parameters
attemptsintThe number of attempts.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Exceptions
- ArgumentOutOfRangeException
attemptsis below 1.
MaxStalledRounds(int)
Sets how many requests in a row may get nothing done before the batch gives up with BatchIncompleteException, in place of 8. A request that writes something starts the
count again, so this bounds a batch that is stuck and not a long one. With 1 the batch gives up at the first request that writes nothing, without a wait, which suits a caller that
has a backoff of its own.
public BatchWriteCommand<T> MaxStalledRounds(int rounds)
Parameters
roundsintThe number of requests.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Exceptions
- ArgumentOutOfRangeException
roundsis below 1.
Put(T)
Adds a put of a whole item, which replaces everything under its key. The item is written to the request here and now, so changing it afterwards changes nothing.
public BatchWriteCommand<T> Put(T item)
Parameters
itemTThe item, which must hold the key attributes.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Exceptions
- ArgumentNullException
itemis null.
PutAll(IEnumerable<T>)
Adds a put of each item, any number of them: SendAsync(CancellationToken) splits the batch into DynamoDB requests of 25 writes for you. An item that fails here fails the whole batch and leaves nothing written.
public BatchWriteCommand<T> PutAll(IEnumerable<T> items)
Parameters
itemsIEnumerable<T>The items, which must hold the key attributes.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Remarks
The whole batch is written into memory here and now, so the sequence is enumerated once, and nothing is sent until SendAsync(CancellationToken). The remarks of BatchWriteCommand<T> say how the requests run and what happens to the writes DynamoDB leaves unprocessed.
Exceptions
- ArgumentNullException
itemsor one of them is null.- KeyFormatException
A key template rejects a value of an item. It names the placeholder, not the item.
Put<TOther>(Table<TOther>, TOther)
Adds a put to another table, or of another type on the same table.
public BatchWriteCommand<T> Put<TOther>(Table<TOther> table, TOther item) where TOther : IDynamoDbDocument<TOther>
Parameters
tableTable<TOther>The table.
itemTOtherThe item, which must hold the key attributes.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
Type Parameters
TOtherThe type of the item.
Exceptions
- ArgumentNullException
tableoritemis null.
ReturnCapacity(ReturnConsumedCapacity)
Asks for the consumed capacity, which goes to ConsumedCapacity and the capacity metric.
public BatchWriteCommand<T> ReturnCapacity(ReturnConsumedCapacity detail = ReturnConsumedCapacity.Total)
Parameters
detailReturnConsumedCapacityHow much detail to return.
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
ReturnMetrics()
Asks for the size estimates of the item collections, which go to ItemCollectionMetrics. DynamoDB has them for tables with a local secondary index.
public BatchWriteCommand<T> ReturnMetrics()
Returns
- BatchWriteCommand<T>
The command, which replaces this one.
SendAsync(CancellationToken)
Sends the batch, in as many requests as it takes. A batch without writes sends nothing and returns an empty result.
public ValueTask<BatchWriteResult> SendAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationTokenCancels the batch, also while it waits between rounds. What was written before stays written.
Returns
- ValueTask<BatchWriteResult>
The result. Await it once.
Exceptions
- InvalidOperationException
The command was already sent, extended or rendered, or it writes an entity with a VersionAttribute without IgnoreVersion().
- BatchIncompleteException
DynamoDB left writes unprocessed after every round, a table stayed throttled on the last attempt of a request, a request timed out, lost its connection or met a server error on its last attempt, or any other failure came after a request went through. The failure is then its InnerException. The exception holds what was not written.
- ObjectDisposedException
The client is disposed.
- ValidationException
DynamoDB rejects the first request, for example because it holds a key twice, or an item above 400 KB.
- ResourceNotFoundException
A table does not exist, as the first request finds.
- DynamoDbException
DynamoDB returns any other error on the first request that repeating cannot fix.
- OperationCanceledException
cancellationTokenwas cancelled. This does not report progress: what went through before stays applied, and nothing says how much that was.
ToRequestJson()
Renders the body of the first request this command would send, as DynamoDB JSON, without sending it. It ends the command, and is meant for tests and debugging. The text contains the items.
public string ToRequestJson()
Returns
- string
The request body.
Exceptions
- InvalidOperationException
The command was already sent, extended or rendered.