View a markdown version of this page

Bloqueo negativo con las transacciones de DynamoDB - Amazon DynamoDB

Bloqueo negativo con las transacciones de DynamoDB

Las transacciones de DynamoDB ofrecen un enfoque de todo o nada para las operaciones agrupadas. Cuando usa TransactWriteItems, DynamoDB supervisa todos los artículos de la transacción. Si alguna operación modifica algún elemento durante la transacción, se cancela toda la transacción y DynamoDB devuelve una TransactionCanceledException. Este comportamiento proporciona una forma de control de la simultaneidad negativo, ya que las modificaciones simultáneas conflictivas se previenen en lugar de detectarse a posteriori.

Cuándo utilizar las transacciones para el bloqueo

Las transacciones son una buena opción cuando:

  • Debe actualizar varios elementos de forma atómica, ya sea dentro de la misma tabla o en varias tablas.

  • La lógica empresarial requiere una semántica de todo o nada, o bien todos los cambios se realizan correctamente o no se aplica ninguno.

Algunos ejemplos habituales son la transferencia de fondos entre cuentas, la realización de pedidos que actualizan el inventario y las tablas de pedidos y el intercambio de elementos entre los jugadores de un juego.

Desventajas

Mayor costo de escritura

Para los elementos de hasta 1 KB, las transacciones consumen 2 WCU por elemento (una para preparar y otra para confirmar), en comparación con 1 WCU para una escritura estándar.

Límite de elementos

Una transacción puede incluir hasta 100 acciones en una o varias tablas.

Sensibilidad a los conflictos

Si otra operación modifica algún elemento de la transacción, toda la transacción produce un error. En situaciones de alta contención, esto puede provocar cancelaciones frecuentes.

Implementación

En el siguiente ejemplo, se utiliza TransactWriteItems para transferir el inventario entre dos elementos de forma atómica. Si otro proceso modifica alguno de los elementos durante la transacción, se anula toda la operación.

import boto3 client = boto3.client('dynamodb') def transfer_inventory(source_id, target_id, quantity): try: client.transact_write_items( TransactItems=[ { 'Update': { 'TableName': 'Inventory', 'Key': {'ItemID': {'S': source_id}}, 'UpdateExpression': 'SET QuantityLeft = QuantityLeft - :qty', 'ConditionExpression': 'QuantityLeft >= :qty', 'ExpressionAttributeValues': { ':qty': {'N': str(quantity)} } } }, { 'Update': { 'TableName': 'Inventory', 'Key': {'ItemID': {'S': target_id}}, 'UpdateExpression': 'SET QuantityLeft = QuantityLeft + :qty', 'ExpressionAttributeValues': { ':qty': {'N': str(quantity)} } } } ] ) return True except client.exceptions.TransactionCanceledException as e: print(f"Transaction canceled: {e}") return False

En este ejemplo, la expresión de condición comprueba que existe suficiente inventario, pero no se necesita ningún atributo de versión. DynamoDB cancela automáticamente la transacción si otra operación modifica algún elemento de la transacción entre las fases de preparación y confirmación. Esto es lo que proporciona el control de simultaneidad negativo, la propia transacción evita las modificaciones simultáneas conflictivas.

nota

Puede combinar transacciones con un bloqueo positivo agregando verificaciones de versión como expresiones de condición adicionales. Esto proporciona una capa adicional de protección, pero no es necesario para que la transacción detecte conflictos.

Para obtener más información, consulte Administración de flujos de trabajo complejos con transacciones de DynamoDB.