Al crear una operación por lotes transaccional, comience a partir de una instancia de contenedor y llame a CreateTransactionalBatch::
PartitionKey partitionKey = new PartitionKey("road-bikes");
TransactionalBatch batch = container.CreateTransactionalBatch(partitionKey);
A continuación, agregue varias operaciones al lote:
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);
Por último, llame a ExecuteAsync en el lote:
using TransactionalBatchResponse response = await batch.ExecuteAsync();
Una vez recibida la respuesta, examine si es correcta. En caso afirmativo, extraiga los resultados:
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
Si se produce un error en la operación, presentará el código de estado del error correspondiente. Todas las demás operaciones tendrán un código de estado 424 (dependencia con error). Si se produce un error en la operación porque intenta crear un elemento que ya existe, se devuelve un código de estado 409 (conflicto). Los códigos de estado facilitan la identificación de la causa del error de la transacción.
Al crear una operación por lotes transaccional, llame a CosmosBatch.createCosmosBatch:
PartitionKey partitionKey = new PartitionKey("road-bikes");
CosmosBatch batch = CosmosBatch.createCosmosBatch(partitionKey);
A continuación, agregue varias operaciones al lote:
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);
Por último, use una instancia de contenedor para llamar a executeCosmosBatch con el lote:
CosmosBatchResponse response = container.executeCosmosBatch(batch);
Una vez recibida la respuesta, examine si es correcta. En caso afirmativo, extraiga los resultados:
if (response.isSuccessStatusCode())
{
List<CosmosBatchOperationResult> results = response.getResults();
}
Importante
Si se produce un error en la operación, presentará el código de estado del error correspondiente. Todas las demás operaciones tendrán un código de estado 424 (dependencia con error). Si se produce un error en la operación porque intenta crear un elemento que ya existe, se devuelve un código de estado 409 (conflicto). Los códigos de estado facilitan la identificación de la causa del error de la transacción.
Obtención o creación de una instancia de contenedor:
container = database.create_container_if_not_exists(id="batch_container",
partition_key=PartitionKey(path='/category'))
En Python, las operaciones por lotes transaccionales tienen un aspecto muy similar a las API de operaciones singulares y son tuplas que contienen operation_type_string, args_tuple y batch_operation_kwargs_dictionary. A continuación se muestran elementos de ejemplo que se usarán para demostrar la funcionalidad de las operaciones por lotes:
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://video2.skills-academy.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"
}
Prepare las operaciones que se van a agregar al lote:
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")})
Agregue las operaciones al lote:
batch_operations = [
create_item_operation,
read_item_operation,
delete_item_operation,
upsert_item_operation,
replace_item_operation,
replace_item_if_match_operation
]
Por último, ejecute el lote:
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 para usar la operación de revisión y la operación replace_if_match_etag en el lote
El diccionario Kwargs de operaciones por lotes es limitado y solo toma tres valores de clave diferentes en total. En el caso de querer usar la aplicación de revisión condicional dentro del lote, el uso de la clave filter_predicate está disponible para la operación de revisión; o en caso de querer usar etags con cualquiera de las operaciones, el uso de las claves if_match_etag/if_none_match_etag también está disponible.
batch_operations = [
("replace", (item_id, item_body), {"if_match_etag": etag}),
("patch", (item_id, operations), {"filter_predicate": filter_predicate, "if_none_match_etag": etag}),
]
Si se produce un error en la operación, presentará el código de estado del error correspondiente. Todas las demás operaciones tendrán un código de estado 424 (dependencia con error). Si se produce un error en la operación porque intenta crear un elemento que ya existe, se devuelve un código de estado 409 (conflicto). Los códigos de estado facilitan la identificación de la causa del error de la transacción.
Ejecución de las operaciones por lotes transaccionales
Cuando se ejecuta el lote transaccional, todas las operaciones de este se agrupan, se serializan en una sola carga y se envían como una única solicitud al servicio Azure Cosmos DB.
El servicio recibe la solicitud, ejecuta todas las operaciones de un ámbito transaccional y devuelve una respuesta con el mismo protocolo de serialización. Esta respuesta indica el fin correcto o un error, y proporciona todas las respuestas de las operaciones individuales.
El SDK le expone la respuesta para que compruebe el resultado y, opcionalmente, extraiga cada uno de los resultados de las operaciones internas.
Limitaciones
Actualmente, hay dos límites conocidos:
- El límite de tamaño de la solicitud de Azure Cosmos DB restringe el tamaño de la carga del lote transaccional para que no supere los 2 MB y que el tiempo máximo de ejecución sea de 5 segundos.
- Hay un límite actual de 100 operaciones por lote transaccional para garantizar que el rendimiento sea el esperado y se sitúe dentro de los Acuerdos de Nivel de Servicio.
Pasos siguientes