Quando si crea un'operazione batch transazionale, iniziare con un'istanza del contenitore e chiamare CreateTransactionalBatch:
PartitionKey partitionKey = new PartitionKey("road-bikes");
TransactionalBatch batch = container.CreateTransactionalBatch(partitionKey);
Aggiungere quindi più operazioni al batch:
Product bike = new (
id: "68719520766",
category: "road-bikes",
name: "Chropen Road Bike"
);
batch.CreateItem<Product>(bike);
Part part = new (
id: "68719519885",
category: "road-bikes",
name: "Tronosuros Tire",
productId: bike.id
);
batch.CreateItem<Part>(part);
Infine, chiamare ExecuteAsync nel batch:
using TransactionalBatchResponse response = await batch.ExecuteAsync();
Una volta ricevuta la risposta, esaminare se abbia avuto esito positivo. Se la risposta indica un esito positivo, estrarre i risultati:
if (response.IsSuccessStatusCode)
{
TransactionalBatchOperationResult<Product> productResponse;
productResponse = response.GetOperationResultAtIndex<Product>(0);
Product productResult = productResponse.Resource;
TransactionalBatchOperationResult<Part> partResponse;
partResponse = response.GetOperationResultAtIndex<Part>(1);
Part partResult = partResponse.Resource;
}
Importante
Se si verifica un errore, l'operazione non riuscita avrà un codice di stato dell'errore corrispondente. Tutte le altre operazioni avranno un codice di stato 424 (dipendenza non riuscita). Se l'operazione non riesce perché tenta di creare un elemento già esistente, viene restituito un codice di stato 409 (conflitto). Il codice di stato consente di identificare la causa dell'errore della transazione.
Quando si crea un'operazione batch transazionale, chiamare CosmosBatch.createCosmosBatch:
PartitionKey partitionKey = new PartitionKey("road-bikes");
CosmosBatch batch = CosmosBatch.createCosmosBatch(partitionKey);
Aggiungere quindi più operazioni al batch:
Product bike = new Product();
bike.setId("68719520766");
bike.setCategory("road-bikes");
bike.setName("Chropen Road Bike");
batch.createItemOperation(bike);
Part part = new Part();
part.setId("68719519885");
part.setCategory("road-bikes");
part.setName("Tronosuros Tire");
part.setProductId(bike.getId());
batch.createItemOperation(part);
Usare infine un'istanza del contenitore per chiamare executeCosmosBatch con il batch:
CosmosBatchResponse response = container.executeCosmosBatch(batch);
Una volta ricevuta la risposta, esaminare se abbia avuto esito positivo. Se la risposta indica un esito positivo, estrarre i risultati:
if (response.isSuccessStatusCode())
{
List<CosmosBatchOperationResult> results = response.getResults();
}
Importante
Se si verifica un errore, l'operazione non riuscita avrà un codice di stato dell'errore corrispondente. Tutte le altre operazioni avranno un codice di stato 424 (dipendenza non riuscita). Se l'operazione non riesce perché tenta di creare un elemento già esistente, viene restituito un codice di stato 409 (conflitto). Il codice di stato consente di identificare la causa dell'errore della transazione.
Ottenere o creare un'istanza del contenitore:
container = database.create_container_if_not_exists(id="batch_container",
partition_key=PartitionKey(path='/category'))
In Python le operazioni di Batch transazionale sono molto simili alle API delle operazioni singolari e sono tuple contenenti (operation_type_string, args_tuple, batch_operation_kwargs_dictionary). Di seguito sono riportati alcuni elementi di esempio che verranno usati per illustrare la funzionalità delle operazioni batch:
create_demo_item = {
"id": "68719520766",
"category": "road-bikes",
"name": "Chropen Road Bike"
}
# for demo, assume that this item already exists in the container.
# the item id will be used for read operation in the batch
read_demo_item1 = {
"id": "68719519884",
"category": "road-bikes",
"name": "Tronosuros Tire",
"productId": "68719520766"
}
# for demo, assume that this item already exists in the container.
# the item id will be used for read operation in the batch
read_demo_item2 = {
"id": "68719519886",
"category": "road-bikes",
"name": "Tronosuros Tire",
"productId": "68719520766"
}
# for demo, assume that this item already exists in the container.
# the item id will be used for read operation in the batch
read_demo_item3 = {
"id": "68719519887",
"category": "road-bikes",
"name": "Tronosuros Tire",
"productId": "68719520766"
}
# for demo, we'll upsert the item with id 68719519885
upsert_demo_item = {
"id": "68719519885",
"category": "road-bikes",
"name": "Tronosuros Tire Upserted",
"productId": "68719520768"
}
# for replace demo, we'll replace the read_demo_item2 with this item
replace_demo_item = {
"id": "68719519886",
"category": "road-bikes",
"name": "Tronosuros Tire replaced",
"productId": "68719520769"
}
# for replace with etag match demo, we'll replace the read_demo_item3 with this item
# The use of etags and if-match/if-none-match options allows users to run conditional replace operations
# based on the etag value passed. When using if-match, the request will only succeed if the item's latest etag
# matches the passed in value. For more on optimistic concurrency control, see the link below:
# https://learn.microsoft.com/azure/cosmos-db/nosql/database-transactions-optimistic-concurrency
replace_demo_item_if_match_operation = {
"id": "68719519887",
"category": "road-bikes",
"name": "Tronosuros Tireh",
"wasReplaced": "Replaced based on etag match"
"productId": "68719520769"
}
Preparare le operazioni da aggiungere al batch:
create_item_operation = ("create", (create_demo_item,), {})
read_item_operation = ("read", ("68719519884",), {})
delete_item_operation = ("delete", ("68719519885",), {})
upsert_item_operation = ("upsert", (upsert_demo_item,), {})
replace_item_operation = ("replace", ("68719519886", replace_demo_item), {})
replace_item_if_match_operation = ("replace",
("68719519887", replace_demo_item_if_match_operation),
{"if_match_etag": container.client_connection.last_response_headers.get("etag")})
Aggiungere le operazioni al batch:
batch_operations = [
create_item_operation,
read_item_operation,
delete_item_operation,
upsert_item_operation,
replace_item_operation,
replace_item_if_match_operation
]
Infine, eseguire il batch:
try:
# Run that list of operations
batch_results = container.execute_item_batch(batch_operations=batch_operations, partition_key="road_bikes")
# Batch results are returned as a list of item operation results - or raise a CosmosBatchOperationError if
# one of the operations failed within your batch request.
print("\nResults for the batch operations: {}\n".format(batch_results))
except exceptions.CosmosBatchOperationError as e:
error_operation_index = e.error_index
error_operation_response = e.operation_responses[error_operation_index]
error_operation = batch_operations[error_operation_index]
print("\nError operation: {}, error operation response: {}\n".format(error_operation, error_operation_response))
# [END handle_batch_error]
Nota per l'uso dell'operazione patch e dell'operazione di replace_if_match_etag nel batch
Il dizionario kwargs dell'operazione batch è limitato e accetta solo un totale di tre valori di chiave diversi. Nel caso di voler usare l'applicazione di patch condizionale all'interno del batch, l'uso di filter_predicate chiave è disponibile per l'operazione di patch o nel caso di voler usare etag con una qualsiasi delle operazioni, è disponibile anche l'uso delle chiavi if_match_etag/if_none_match_etag.
batch_operations = [
("replace", (item_id, item_body), {"if_match_etag": etag}),
("patch", (item_id, operations), {"filter_predicate": filter_predicate, "if_none_match_etag": etag}),
]
Se si verifica un errore, l'operazione non riuscita avrà un codice di stato dell'errore corrispondente. Tutte le altre operazioni avranno un codice di stato 424 (dipendenza non riuscita). Se l'operazione non riesce perché tenta di creare un elemento già esistente, viene restituito un codice di stato 409 (conflitto). Il codice di stato consente di identificare la causa dell'errore della transazione.
Come vengono eseguite le operazioni batch transazionali
Quando viene eseguito il batch transazionale, tutte le operazioni nel batch transazionale vengono raggruppate, serializzate in un singolo payload e inviate come singola richiesta al servizio Azure Cosmos DB.
Il servizio riceve la richiesta ed esegue tutte le operazioni all'interno di un ambito transazionale e restituisce una risposta usando lo stesso protocollo di serializzazione. Questa risposta è un esito positivo o negativo e fornisce risposte singole per ogni operazione.
L'SDK espone la risposta per verificare il risultato e, facoltativamente, estrarre ognuno dei risultati dell'operazione interna.
Limiti
Attualmente sono presenti due limiti noti:
- Il limite delle dimensioni delle richieste di Azure Cosmos DB vincola le dimensioni del payload del batch transazionale a non superare 2 MB e il tempo massimo di esecuzione è di 5 secondi.
- Esiste un limite corrente di 100 operazioni per batch transazionale per garantire che le prestazioni siano come previsto e all'interno dei contratti di servizio.
Passaggi successivi