Funcionamiento de las Transacciones de Amazon DynamoDB
Con Amazon DynamoDB Transactions, puede agrupar varias acciones y enviarlas como una sola operación TransactWriteItems
o TransactGetItems
de tipo "todo o nada". En las secciones siguientes, se describen las operaciones de la API, la administración de la capacidad, las prácticas recomendadas y otros detalles sobre el uso de operaciones transaccionales en DynamoDB.
Temas
- API TransactWriteItems
- API TransactGetItems
- Niveles de aislamiento para las transacciones de DynamoDB
- Gestión de conflictos de transacciones en DynamoDB
- Uso de las API transaccionales en DynamoDB Accelerator (DAX)
- Administración de la capacidad para las transacciones
- Prácticas recomendadas para las transacciones
- Uso de las API transaccionales con tablas globales
- Transacciones de DynamoDB en comparación con la biblioteca de transacciones del cliente de AWSLabs
API TransactWriteItems
TransactWriteItems
es una operación de escritura síncrona e idempotente que agrupa hasta 100 acciones de escritura en una única operación de tipo “todo o nada”. Estas acciones pueden estar dirigidas a un máximo de 100 elementos diferenciados en una o varias tablas de DynamoDB en la misma cuenta de AWS y en la misma región. El tamaño total de los elementos de la transacción no puede superar 4 MB. Las acciones se realizan atómicamente, de tal forma que se llevan a cabo correctamente todas o ninguna de ellas.
nota
-
Una operación
TransactWriteItems
se diferencia de una operaciónBatchWriteItem
en que todas las acciones que contiene deben completarse correctamente o, de lo contrario, no se realiza ningún cambio. Con una operaciónBatchWriteItem
, es posible que solo algunas de las acciones del lote se realicen correctamente y otras, no. -
Las transacciones no se pueden realizar mediante índices.
No se pueden dirigir varias operaciones de la misma transacción al mismo elemento. Por ejemplo, no se puede realizar una acción ConditionCheck
y también una acción Update
en el mismo elemento de la misma transacción.
Puede agregar los tipos de acciones siguientes a una transacción:
-
Put
: Inicia una operaciónPutItem
para crear un nuevo elemento o sustituir uno antiguo por otro nuevo, ya sea de forma condicional o sin especificar ninguna condición. -
Update
: Inicia una operaciónUpdateItem
para editar los atributos de un elemento existente o agregar un nuevo elemento a la tabla, si no existe ya. Esta acción se utiliza para agregar, eliminar o actualizar atributos a un elemento existente, de forma condicional o sin condiciones. -
Delete
: Inicia una operaciónDeleteItem
para eliminar un solo elemento de una tabla identificado por su clave principal. -
ConditionCheck
: Comprueba la existencia de un elemento o la condición de atributos concretos del elemento.
Una vez que la transacción se completa, los cambios realizados con transacciones se propagan a índices secundarios globales (GSI), secuencias y copias de seguridad. Como la propagación no es inmediata ni instantánea, si se restaura una tabla a partir de una copia de seguridad (RestoreTableFromBackup) o se exporta a un punto en el medio de la propagación (ExportTableToPointInTime), podría contener algunos pero no todos los cambios realizados durante una transacción reciente.
Idempotencia
Opcionalmente, puede incluir un token de cliente al realizar una llamada a TransactWriteItems
para asegurarse de que la solicitud sea idempotente. Hacer que las transacciones sean idempotentes ayuda a evitar errores de aplicaciones si se envía la misma operación varias veces debido a una interrupción de la conexión u otro problema de conectividad.
Si la llamada a TransactWriteItems
original se realizó correctamente, las llamadas siguientes a TransactWriteItems
con el mismo token de cliente también se devolverán correctamente sin hacer ningún cambio. Si se ha establecido el parámetro ReturnConsumedCapacity
, la llamada TransactWriteItems
inicial devolverá el número de unidades de capacidad de escritura consumidas al realizar los cambios. Las llamadas siguientes a TransactWriteItems
con el mismo token de cliente devolverán el número de unidades de capacidad de lectura consumidas al leer el elemento.
Información importante sobre la idempotencia
-
Un token de cliente es válido durante 10 minutos desde que finaliza la solicitud que lo utiliza. Transcurridos esos 10 minutos, cualquier solicitud que use el mismo token de cliente se tratará como si fuera nueva. No debe reutilizar el mismo token de cliente para la misma solicitud si han pasado 10 minutos.
-
Si repite una solicitud con el mismo token de cliente dentro del periodo de idempotencia de 10 minutos, pero cambia algún otro parámetro de la solicitud, DynamoDB devolverá una excepción
IdempotentParameterMismatch
.
Control de errores de escritura
Las transacciones de escritura no se realizarán correctamente en las siguientes circunstancias:
-
Cuando no se cumple alguna de las condiciones de las expresiones de condición.
-
Cuando se produce un error de validación de transacción porque hay más de una acción dirigida al mismo elemento en una sola operación
TransactWriteItems
. -
Cuando una solicitud
TransactWriteItems
está en conflicto con una operaciónTransactWriteItems
en curso para uno o varios elementos de la solicitudTransactWriteItems
. En este caso, la solicitud genera un errorTransactionCanceledException
. -
Cuando no hay suficiente capacidad aprovisionada para completar la transacción.
-
Cuando el tamaño de un elemento es excesivo (más de 400 KB), un índice secundario local (LSI) se vuelve demasiado grande o se produce algún error de validación semejante a causa de los cambios realizados por la transacción.
-
Cuando hay algún error de usuario, como un formato de datos no válido.
Para obtener más información acerca de cómo se manejan los conflictos con operaciones TransactWriteItems
, consulte Gestión de conflictos de transacciones en DynamoDB.
API TransactGetItems
TransactGetItems
es una operación de lectura síncrona que agrupa hasta 100 acciones Get
. Estas acciones pueden estar dirigidas a un máximo de 100 elementos diferenciados en una o varias tablas de DynamoDB en la misma cuenta y región de AWS. El tamaño total de los elementos de la transacción no puede superar 4 MB.
Las acciones Get
se realizan atómicamente, de tal forma que se llevan a cabo correctamente todas o ninguna de ellas:
-
Get
: Inicia una operaciónGetItem
para recuperar un conjunto de atributos para el elemento que tiene la clave principal especificada. Si no se encuentra ningún elemento que coincida,Get
no devuelve ningún dato.
Control de errores de lectura
Las transacciones de lectura no se realizarán correctamente en las siguientes circunstancias:
-
Cuando una solicitud
TransactGetItems
está en conflicto con una operaciónTransactWriteItems
en curso para uno o varios elementos de la solicitudTransactGetItems
. En este caso, la solicitud genera un errorTransactionCanceledException
. -
Cuando no hay suficiente capacidad aprovisionada para completar la transacción.
-
Cuando hay algún error de usuario, como un formato de datos no válido.
Para obtener más información acerca de cómo se manejan los conflictos con operaciones TransactGetItems
, consulte Gestión de conflictos de transacciones en DynamoDB.
Niveles de aislamiento para las transacciones de DynamoDB
Los niveles de aislamiento de las operaciones transaccionales (TransactWriteItems
o TransactGetItems
) y otras operaciones son los siguientes.
SERIALIZABLE
El aislamiento serializable garantiza que los resultados de varias operaciones concurrentes sean iguales que si ninguna operación se hubiera iniciado antes de finalizar la anterior.
Existe aislamiento serializable entre los siguientes tipos de operaciones:
-
Entre cualquier operación transaccional y cualquier operación de escritura estándar (
PutItem
,UpdateItem
oDeleteItem
). -
Entre cualquier operación transaccional y cualquier operación de lectura estándar (
GetItem
). -
Entre una operación
TransactWriteItems
y una operaciónTransactGetItems
.
Aunque existe aislamiento serializable entre las operaciones transaccionales y cada escritura estándar individual escribe en una operación BatchWriteItem
, no se produce aislamiento serializable entre la transacción y la operación BatchWriteItem
como una unidad.
Del mismo modo, el nivel de aislamiento entre una operación transaccional y una operación GetItems
individual de una operación BatchGetItem
es serializable. Pero el nivel de aislamiento entre la transacción y la operación BatchGetItem
como unidad es de lectura confirmada.
Una sola solicitud GetItem
es serializable con respecto a una solicitud TransactWriteItems
de una de las dos formas siguientes: antes o después de la solicitud TransactWriteItems
. Multiple solicitudes GetItem
, de las claves en solicitudes TransactWriteItems
se pueden ejecutar en cualquier orden, y por lo tanto los resultados son lectura confirmada.
Por ejemplo, si las solicitudes GetItem
para el elemento A y el elemento B se ejecutan simultáneamente con una solicitud TransactWriteItems
que modifica tanto el punto A como el punto B, hay cuatro posibilidades:
-
Ambos
GetItem
se ejecutan antes de que la solicitudTransactWriteItems
. -
Ambos
GetItem
se ejecutan después de la solicitudTransactWriteItems
. -
Solicitud
GetItem
para el elemento A se ejecuta antes de la solicitudTransactWriteItems
. Para el elemento B,GetItem
se ejecuta después deTransactWriteItems
. -
Solicitud
GetItem
para el elemento B se ejecuta antes de la solicitudTransactWriteItems
. Para el elemento A,GetItem
se ejecuta después deTransactWriteItems
.
Utilice TransactGetItems
, si prefiere el nivel de aislamiento serializable para múltiples solicitudes GetItem
.
Si se realiza una lectura no transaccional de varios elementos que formaban parte de la misma solicitud de escritura de transacción durante el vuelo, es posible que pueda leer el nuevo estado de algunos de los elementos y el estado anterior de los demás. Solo podrá leer el nuevo estado de todos los elementos que formaban parte de la solicitud de escritura de la transacción cuando reciba una respuesta correcta a la escritura de la transacción.
LECTURA CONFIRMADA
El aislamiento de lectura confirmada garantiza que las operaciones de lectura siempre devuelven valores confirmados para un elemento: la lectura nunca presentará una vista al elemento que represente un estado de una escritura transaccional que no haya tenido éxito finalmente. El aislamiento de lectura confirmada no impide las modificaciones del elemento inmediatamente después de la operación de lectura.
El nivel de aislamiento es de lectura confirmada entre cualquier operación transaccional y cualquier operación de lectura que conlleve varias lecturas estándar (BatchGetItem
, Query
o Scan
). Si una escritura transaccional actualiza un elemento en medio de una operación de BatchGetItem
, Query
o Scan
, la parte posterior de la operación de lectura devuelve el nuevo valor confirmado (con ConsistentRead)
o posiblemente un valor confirmado anterior [lecturas coherentes posteriores]).
Resumen de la operación
A modo de resumen, en la siguiente tabla se indican los niveles de aislamiento entre una operación transaccional (TransactWriteItems
o TransactGetItems
) y otras operaciones.
Operación | Nivel de aislamiento |
---|---|
|
Serializable |
|
Serializable |
|
Serializable |
|
Serializable |
|
Lectura confirmada* |
|
NO serializable* |
|
Lectura confirmada |
|
Lectura confirmada |
Otra operación transaccional |
Serializable |
Los niveles marcados con un asterisco (*) se aplican a la operación como una unidad. Sin embargo, las acciones individuales contenidas en esas operaciones tienen el nivel de aislamiento serializable.
Gestión de conflictos de transacciones en DynamoDB
Un conflicto de transacciones puede producirse durante solicitudes concurrentes de nivel de elemento en un elemento dentro de una transacción. Los conflictos de transacciones pueden producirse en los siguientes escenarios:
-
Una solicitud
PutItem
,UpdateItem
oDeleteItem
de un elemento entra en conflicto con una solicitudTransactWriteItems
en curso que incluye el mismo elemento. -
Un elemento incluido en una solicitud
TransactWriteItems
forma parte de otra solicitudTransactWriteItems
en curso. -
Un elemento incluido en una solicitud
TransactGetItems
forma parte de otra solicitudTransactWriteItems
,BatchWriteItem
,PutItem
,UpdateItem
oDeleteItem
en curso.
nota
-
Cuando se rechaza una solicitud
PutItem
,UpdateItem
oDeleteItem
, la solicitud no se realiza correctamente y genera una excepciónTransactionConflictException
. -
Si se rechaza cualquier solicitud de nivel de elemento dentro de una operación
TransactWriteItems
oTransactGetItems
, la solicitud no se realiza correctamente y genera una excepciónTransactionCanceledException
. Si esa solicitud falla, los SDK de AWS no vuelven a intentar la solicitud.Si se está utilizando el AWS SDK for Java, la excepción contiene la lista de CancellationReasons, ordenada según la lista de elementos del parámetro
TransactItems
de la solicitud. Para los demás lenguajes, se incluye una representación de cadena de la lista en el mensaje de error de la excepción. -
Si una operación
TransactWriteItems
oTransactGetItems
está en conflicto con una solicitudGetItem
concurrente, las dos operaciones podrían realizarse correctamente.
La métrica TransactionConflict de CloudWatch se incrementa para cada solicitud de nivel de elemento que no se realiza correctamente.
Uso de las API transaccionales en DynamoDB Accelerator (DAX)
Tanto TransactWriteItems
como TransactGetItems
se admiten en DynamoDB Accelerator (DAX) con los mismos niveles de aislamiento que en DynamoDB.
TransactWriteItems
escribe a través de DAX. DAX pasa una llamada TransactWriteItems
a DynamoDB y devuelve la respuesta. Para rellenar la caché después de la escritura, DAX llama a TransactGetItems
en segundo plano para cada elemento en la operación TransactWriteItems
, que consume unidades de capacidad de lectura adicionales. (Para obtener más información, consulte Administración de la capacidad para las transacciones). Esta funcionalidad le permite no complicar la lógica de la aplicación y utilizar DAX para operaciones transaccionales así como para operaciones no transaccionales.
Las llamadas TransactGetItems
se pasan por DAX sin que los elementos se almacenen en caché localmente. Es el mismo comportamiento que tienen las API de lectura de consistencia alta en DAX.
Administración de la capacidad para las transacciones
Habilitar las transacciones para las tablas de DynamoDB no conlleva ningún coste adicional. Usted paga sólo por las lecturas o escrituras que forman parte de su transacción. DynamoDB lleva a cabo dos lecturas o escrituras subyacentes de cada elemento de la transacción: una para preparar la transacción y otra para confirmarla. Las dos operaciones de lectura/escritura subyacentes están visibles en las métricas de Amazon CloudWatch.
Planee las lecturas y escrituras adicionales que requieren las API transaccionales al aprovisionar la capacidad para las tablas. Por ejemplo, supongamos que su aplicación ejecuta una transacción por segundo y que cada transacción escribe tres elementos de 500 bites en la tabla. Cada elemento requiere dos unidades de capacidad de escritura (WCU): una para preparar la transacción y otra para confirmarla. Por consiguiente, tendría que aprovisionar seis WCU para la tabla.
Si utilizó DynamoDB Accelerator (DAX) en el ejemplo anterior, también debió utilizar dos unidades de capacidad de lectura (RCU) para cada elemento de la llamada TransactWriteItems
. Por tanto, tendría que aprovisionar seis RCU adicionales para la tabla.
Del mismo modo, si la aplicación ejecuta una transacción de lectura por segundo y cada transacción lee tres elementos de 500 bytes de la tabla, debería aprovisionar seis unidades de capacidad de lectura (RCU) para la tabla. La lectura de cada elemento requiere dos RCU: una para preparar la transacción y otra para confirmarla.
Además, el comportamiento predeterminado del SDK consiste en reintentar las transacciones si se produce alguna excepción TransactionInProgressException
. Planee las unidades de capacidad de lectura (RCU) adicionales que consumen estos reintentos. Lo mismo sucede si reintenta transacciones de su propio código mediante un ClientRequestToken
.
Prácticas recomendadas para las transacciones
Es importante tener en cuenta las prácticas recomendadas siguientes al utilizar transacciones de DynamoDB.
-
Habilite el escalado automático en las tablas o asegúrese de haber aprovisionado suficiente capacidad de rendimiento para llevar a cabo las dos operaciones de lectura o escritura para cada elemento de la transacción.
-
Si no utiliza un SDK proporcionado por AWS, incluya un atributo
ClientRequestToken
al realizar una llamada aTransactWriteItems
para asegurarse de que la solicitud sea idempotente. -
No agrupe las operaciones en una transacción si no es necesario. Por ejemplo, si una misma transacción compuesta de 10 operaciones se puede desglosar en varias transacciones de modo que la aplicación continúe siendo correcta, recomendamos dividir la transacción. Usar transacciones más sencillas mejora el rendimiento y aumenta la probabilidad de que se ejecuten correctamente.
-
Si varias transacciones actualizan los mismos elementos de forma simultánea, pueden provocar conflictos que cancelen las transacciones. Recomendamos las siguientes prácticas recomendadas de DynamoDB para modelar los datos de tal forma que se reduzcan al mínimo esos conflictos.
-
Si un conjunto de atributos se actualiza a menudo para varios elementos durante una misma transacción, puede ser conveniente agrupar los atributos en un solo elemento para reducir el ámbito de la transacción.
-
Evite utilizar transacciones para la ingesta masiva de datos. Para las escrituras masivas, es preferible usar
BatchWriteItem
.
Uso de las API transaccionales con tablas globales
Las operaciones incluidas en una transacción de DynamoDB solo se garantizan como transaccionales en la región en la que se ha ejecutado originalmente la transacción. La transaccionalidad no se conserva cuando los cambios aplicados a una transacción se replican en todas las regiones en réplicas de tablas globales.
Transacciones de DynamoDB en comparación con la biblioteca de transacciones del cliente de AWSLabs
Las transacciones de DynamoDB proporcionan una forma más rentable, robusta y eficiente de sustituir la biblioteca de cliente de transacciones de AWSLabs