Avanzado6 min de lectura

Transacciones de DynamoDB

Una transacción de DynamoDB agrupa varias escrituras en una sola operación todo-o-nada: o se confirman todas las acciones, o ninguna. Es la forma de evitar que dos Items relacionados se desincronicen cuando una escritura falla a medias.

En el escenario del registro de auditoría, cada evento que añades también debería incrementar un eventCount por tenant. Si el evento aterriza pero el contador no — o viceversa — el registro y el conteo discrepan para siempre. Una transacción lo hace imposible.

¿Admite DynamoDB las transacciones?

Sí. DynamoDB admite transacciones ACID mediante TransactWriteItems y TransactGetItems, que agrupan hasta 100 acciones en una sola operación todo-o-nada en una o más tablas. O se confirman todas las escrituras o ninguna, por lo que los Items relacionados no pueden desincronizarse. Las escrituras transaccionales consumen el doble de capacidad que las escrituras normales, y una condición fallida o un conflicto cancela toda la solicitud.

  • TransactWriteItems agrupa hasta 100 acciones de escritura en una o más tablas, todo-o-nada. El tamaño agregado de los Items no puede superar los 4 MB.
  • Las acciones son Put, Update, Delete y ConditionCheck. Un ConditionCheck afirma algo sobre un Item que no estás escribiendo.
  • Cuesta el doble. Una escritura transaccional consume el doble de capacidad que una escritura normal — DynamoDB prepara y luego confirma.
  • Los conflictos y las condiciones fallidas cancelan todo con una TransactionCanceledException; no queda nada parcial.

El problema: dos escrituras que deben coincidir

Quieres que cada evento de auditoría nuevo también incremente el conteo acumulado del tenant. Hecho como dos llamadas separadas, cualquier fallo entre ellas corrompe tus datos:

  1. PutItem del nuevo Item EVENT#… — tiene éxito.
  2. UpdateItem a ADD eventCount 1 — agota su tiempo de espera.

Ahora el registro tiene una fila más de las que afirma el contador. Reintentar el paso 2 a ciegas arriesga el doble conteo; no reintentarlo los deja inconsistentes. No hay recuperación segura porque las dos escrituras nunca estuvieron vinculadas.

Viniendo de SQL, envolverías ambas en BEGIN … COMMIT. La respuesta de DynamoDB es una única petición transaccional que lleva ambas escrituras juntas.

Cómo funciona TransactWriteItems

Según la Guía para desarrolladores de AWS, TransactWriteItems "agrupa hasta 100 acciones de escritura en una sola operación todo-o-nada" dirigida a hasta 100 Items distintos, y "el tamaño agregado de los Items de la transacción no puede superar los 4 MB". Las acciones se completan de forma atómica — todas tienen éxito o ninguna.

Puedes mezclar cuatro tipos de acción en una transacción:

  • Put — crea o reemplaza un Item.
  • Update — edita atributos (incluido ADD para nuestro contador).
  • Delete — elimina un Item por clave.
  • ConditionCheck — afirma una condición sobre un Item que no estás escribiendo de otro modo (p. ej. "este tenant sigue activo").

Dos reglas más muerden en la práctica. Primero, las transacciones consumen el doble de capacidad que las escrituras no transaccionales equivalentes — DynamoDB hace una fase de preparación y una fase de confirmación. Segundo, no puedes apuntar dos veces al mismo Item en una transacción, y las transacciones no se pueden ejecutar contra índices.

"DynamoDB"App"DynamoDB"Appprepare both, checkconditions"TransactWriteItems [Put EVENT,Update counter]""both commit, orTransactionCanceledException"

Un ejemplo práctico: añadir + contar, de forma atómica

De vuelta al registro de auditoría. Añadir un evento para el tenant acme e incrementar su contador es una transacción con dos acciones:

actionitemeffect
PutTENANT#acmeEVENT#2026-06-24T09:14Z#a1write the new audit row
UpdateTENANT#acmeCOUNTERADD eventCount 1

Si la condición de cualquiera de las acciones falla — digamos un ConditionCheck de que el tenant no está suspendido — toda la petición se cancela con una TransactionCanceledException y ninguna escritura ocurre. El registro y el contador nunca pueden discrepar.

La ConditionExpression de cada acción es la palanca. Para afirmar que la fila del evento aún no existe (de modo que un reintento no pueda duplicarla) y que el tenant está activo, compones condiciones como attribute_not_exists(SK) en el Put y status = :active como un ConditionCheck.

Construye y copia esas expresiones de condición tipadas en el DynamoDB Expression Builder en lugar de ensamblar a mano ExpressionAttributeNames y placeholders :val — el modo de escritura condicional emite exactamente la forma que TransactWriteItems quiere.

Para reintentos seguros sobre una conexión inestable, adjunta un client token: un TransactWriteItems repetido con el mismo token en un plazo de 10 minutos devuelve éxito sin volver a aplicar las escrituras (idempotencia).

Hazlo en DynoTable

DynoTable usa transacciones internamente para sus propias escrituras: cuando preparas varias ediciones de Items y las confirmas, las envía como TransactWriteItems con expresiones de condición de bloqueo optimista, así que tu lote de ediciones es todo-o-nada — nunca aplicas a medias un cambio multi-Item.

Eso significa que puedes editar la fila del evento y el contador en el mismo lote preparado, revisar el diff y confirmar ambos de forma atómica sin escribir nada de código de SDK.

Preparando el nuevo evento de auditoría y la edición del contador del tenant en DynoTable, y confirmando ambos como una transacción todo-o-nada.
Preparando el nuevo evento de auditoría y la edición del contador del tenant en DynoTable, y confirmando ambos como una transacción todo-o-nada.

Trampas y próximos pasos

  • Presupuesta el doble de capacidad. Una escritura transaccional factura el doble de WCU que una escritura simple — bien para el par ocasional crítico para la consistencia, caro si envuelves cada escritura en una transacción. Úsalo donde la atomicidad realmente importa.
  • Gestiona TransactionCanceledException explícitamente. Se devuelve por una condición fallida o un conflicto con otra transacción en vuelo sobre los mismos Items. Los motivos de cancelación te dicen qué acción falló — inspecciónalos, no reintentes a ciegas.
  • Los registros de stream no son conscientes de las transacciones. Los cambios de una transacción se propagan a Streams de forma gradual y pueden intercalarse con otros; los consumidores no pueden asumir atomicidad ni orden — ver DynamoDB Streams.
  • No para contadores de alto rendimiento. Un solo contador caliente bajo una carga transaccional concurrente intensa sufrirá throttling; para eso, mira los contadores atómicos o fragmentar el contador.

Las transacciones son la herramienta para "estas escrituras deben coincidir". Una vez que los eventos aterrizan de forma consistente, la siguiente preocupación es reaccionar a ellos — eso es DynamoDB Streams.

Descargar DynoTable para preparar ediciones multi-Item y confirmarlas como una sola transacción contra tu propia tabla.

Actualizado