Use extensiones para personalizar las operaciones de DynamoDB Enhanced Client - AWS SDK for Java 2.x

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Use extensiones para personalizar las operaciones de DynamoDB Enhanced Client

La API del cliente mejorado de DynamoDB admite extensiones de complementos que proporcionan funciones que van más allá de las operaciones de mapeo. Las extensiones utilizan dos métodos de enlace para modificar los datos durante las operaciones de lectura y escritura:

  • beforeWrite()- Modifica una operación de escritura antes de que se produzca

  • afterRead()- Modifica los resultados de una operación de lectura después de que se produzca

Algunas operaciones (como las actualizaciones de elementos) realizan tanto una escritura como una lectura, por lo que se recurre a ambos métodos de enlace.

Cómo se cargan las extensiones

Las extensiones se cargan en el orden que especifique en el generador de clientes mejorado. El orden de carga puede ser importante porque una extensión puede actuar sobre valores que han sido transformados por una extensión anterior.

De forma predeterminada, el cliente mejorado carga dos extensiones:

Puede anular el comportamiento predeterminado con el generador de clientes mejorado y cargar cualquier extensión. También puede no especificar ninguna si no desea utilizar las extensiones predeterminadas.

importante

Si carga sus propias extensiones, el cliente mejorado no carga ninguna extensión predeterminada. Si desea el comportamiento proporcionado por alguna de las extensiones predeterminadas, deberá añadirla explícitamente a la lista de extensiones.

El siguiente ejemplo muestra cómo cargar una extensión personalizada con el verifyChecksumExtension VersionedRecordExtension nombre de. La AtomicCounterExtension no se carga en este ejemplo.

DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build(); DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(dynamoDbClient) .extensions(versionedRecordExtension, verifyChecksumExtension) .build();

Detalles y configuración de la extensión disponibles

En las siguientes secciones se proporciona información detallada sobre cada extensión disponible en el SDK.

Implemente un bloqueo optimista con el VersionedRecordExtension

La VersionedRecordExtension extensión proporciona un bloqueo optimista al incrementar y rastrear el número de versión de un elemento a medida que los elementos se escriben en la base de datos. Se añade una condición a cada escritura que provoca un error en la escritura si el número de versión del elemento persistente real no coincide con el valor que leyó la aplicación por última vez.

Configuración

Para especificar qué atributo usar para rastrear el número de versión del elemento, etiquete un atributo numérico en el esquema de la tabla.

El siguiente fragmento especifica que el atributo version debe contener el número de versión del artículo.

@DynamoDbVersionAttribute public Integer getVersion() {...}; public void setVersion(Integer version) {...};

El enfoque equivalente del esquema de tabla estático se muestra en el siguiente fragmento.

.addAttribute(Integer.class, a -> a.name("version") .getter(Customer::getVersion) .setter(Customer::setVersion) // Apply the 'version' tag to the attribute. .tags(VersionedRecordExtension.AttributeTags.versionAttribute())

Funcionamiento

El bloqueo optimista con el VersionedRecordExtension tiene el siguiente impacto en estos DynamoDbEnhancedClient DynamoDbTable métodos:

putItem

A los nuevos elementos se les asigna un valor de versión inicial de 0. Esto se puede configurar con@DynamoDbVersionAttribute(startAt = X).

updateItem

Si recupera un elemento, actualiza una o más de sus propiedades e intenta guardar los cambios, la operación solo se realizará correctamente si el número de versión del lado del cliente y el del servidor coinciden.

Si se realiza correctamente, el número de versión se incrementa automáticamente en 1. Esto se puede configurar con@DynamoDbVersionAttribute(incrementBy = X).

deleteItem

La DynamoDbVersionAttribute anotación no tiene ningún efecto. Debe añadir una expresión de condición manualmente al eliminar un elemento.

En el siguiente ejemplo, se agrega una expresión condicional para garantizar que el elemento eliminado es el elemento que se ha leído. En el siguiente ejemplo, recordVersion se anota el atributo del frijol con@DynamoDbVersionAttribute.

// 1. Read the item and get its current version. Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build()); // `recordVersion` is the bean's attribute that is annotated with `@DynamoDbVersionAttribute`. AttributeValue currentVersion = item.getRecordVersion(); // 2. Create conditional delete with the `currentVersion` value. DeleteItemEnhancedRequest deleteItemRequest = DeleteItemEnhancedRequest.builder() .key(KEY) .conditionExpression(Expression.builder() .expression("recordVersion = :current_version_value") .putExpressionValue(":current_version_value", currentVersion) .build()).build(); customerTable.deleteItem(deleteItemRequest);
transactWriteItems
  • addPutItem: Este método tiene el mismo comportamiento queputItem.

  • addUpdateItem: Este método tiene el mismo comportamiento queupdateItem.

  • addDeleteItem: Este método tiene el mismo comportamiento quedeleteItem.

batchWriteItem
  • addPutItem: Este método tiene el mismo comportamiento queputItem.

  • addDeleteItem: Este método tiene el mismo comportamiento quedeleteItem.

nota

Las tablas globales de DynamoDB utilizan una conciliación entre actualizaciones simultáneas según la cual el último autor gana, mientras que DynamoDB hace todo lo posible por determinar quién es el último que escribe. Si utiliza tablas globales, esta política de «el último autor gana» significa que las estrategias de bloqueo pueden no funcionar como se esperaba, ya que todas las réplicas acabarán convergiendo en función de la última escritura determinada por DynamoDB.

¿Cómo deshabilitar

Para deshabilitar el bloqueo optimista, no utilice la @DynamoDbVersionAttribute anotación.

Implemente contadores con el AtomicCounterExtension

La AtomicCounterExtension extensión incrementa un atributo numérico etiquetado cada vez que se escribe un registro en la base de datos. Puede especificar valores iniciales e incrementales. Si no se especifica ningún valor, el valor inicial se establece en 0 y el valor del atributo se incrementa en 1.

Configuración

Para especificar qué atributo es un contador, etiquete un atributo de tipo Long en el esquema de la tabla.

En el siguiente fragmento se muestra el uso de los valores de inicio e incremento predeterminados para el atributo counter.

@DynamoDbAtomicCounter public Long getCounter() {...}; public void setCounter(Long counter) {...};

El enfoque del esquema de tabla estático se muestra en el siguiente fragmento. La extensión del contador atómico utiliza un valor inicial de 10 e incrementa el valor en 5 cada vez que se escribe el registro.

.addAttribute(Integer.class, a -> a.name("counter") .getter(Customer::getCounter) .setter(Customer::setCounter) // Apply the 'atomicCounter' tag to the attribute with start and increment values. .tags(StaticAttributeTags.atomicCounter(10L, 5L))

Añada marcas de tiempo con el AutoGeneratedTimestampRecordExtension

La AutoGeneratedTimestampRecordExtension extensión actualiza automáticamente los atributos del tipo etiquetado Instant con una marca de tiempo actual cada vez que el elemento se escribe correctamente en la base de datos. Esta extensión no se carga de forma predeterminada.

Configuración

Para especificar qué atributo actualizar con la marca de tiempo actual, etiquete el atributo Instant en el esquema de la tabla.

El lastUpdate atributo es el objetivo del comportamiento de la extensión en el siguiente fragmento. Tenga en cuenta el requisito de que el atributo debe ser de tipo Instant.

@DynamoDbAutoGeneratedTimestampAttribute public Instant getLastUpdate() {...} public void setLastUpdate(Instant lastUpdate) {...}

El enfoque equivalente del esquema de tabla estático se muestra en el siguiente fragmento.

.addAttribute(Instant.class, a -> a.name("lastUpdate") .getter(Customer::getLastUpdate) .setter(Customer::setLastUpdate) // Applying the 'autoGeneratedTimestamp' tag to the attribute. .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())

Genera un UUID con AutoGeneratedUuidExtension

La AutoGeneratedUuidExtension extensión genera un UUID (identificador único universal) único para un atributo cuando se escribe un nuevo registro en la base de datos. Utiliza el método UUID.randomUUID () de Java JDK y se aplica a los atributos de tipo. java.lang.String Esta extensión no se carga de forma predeterminada.

Configuración

El uniqueId atributo es el objetivo del comportamiento de la extensión en el siguiente fragmento.

@AutoGeneratedUuidExtension public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

El enfoque equivalente del esquema de tabla estático se muestra en el siguiente fragmento.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute())

Si quieres que la extensión rellene el UUID solo para los putItem métodos y no para los updateItem métodos, añade la anotación de actualización del comportamiento, tal y como se muestra en el siguiente fragmento.

@AutoGeneratedUuidExtension @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS) public String getUniqueId() {...} public void setUniqueId(String uniqueId) {...}

Si utilizas el enfoque de esquema de tabla estática, usa el siguiente código equivalente.

.addAttribute(String.class, a -> a.name("uniqueId") .getter(Customer::getUniqueId) .setter(Customer::setUniqueId) // Applying the 'autoGeneratedUuid' tag to the attribute. .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute(), StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS))