Introduction
Une nouvelle tentative de soumission de commande ne doit pas écraser un montant existant. Une mise à jour de paiement périmée ne doit pas non plus écraser une version plus récente. Vous allez effectuer de véritables requêtes API conditionnelles, observer le rejet des doublons et des versions périmées, puis prouver que de nouvelles commandes valides réussissent toujours.
Terminez d'abord Créer une table DynamoDB pour les commandes, notamment les éléments typés et les expressions de mise à jour. Cette nouvelle unité ne réutilise aucune table ni aucun identifiant d'accès antérieur. Utilisez /home/labex/project, la CLI AWS officielle et AWS View.
Lien avec les certifications
| Certification | Tâche de l’examen | Pratique |
|---|---|---|
| Developer – Associate (DVA-C02) | Tâche 1.3, Tâche 1.1 | Écritures conditionnelles DynamoDB et concurrence optimiste. |
Vue d’ensemble du laboratoire

Protéger la création de la première commande
Dans cette étape, vous allez créer une commande uniquement si sa clé primaire est inutilisée. Un PutItem sans condition remplace l'élément entier à cette clé. Une condition vérifie l'état courant de façon atomique avec l'écriture : une vérification distincte par lecture puis écriture est donc inutile et permettrait des conflits entre opérations concurrentes.
Utilisez la connexion temporaire préparée et créez une table indépendante avec l'identifiant de commande comme clé de partition String.
cd /home/labex/project
aws sts get-caller-identity
aws dynamodb create-table \
--table-name labex-d04-orders \
--attribute-definitions AttributeName=order_id,AttributeType=S \
--key-schema AttributeName=order_id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
aws dynamodb wait table-exists --table-name labex-d04-orders
Écrivez un fichier ordinaire de requête API. Le heredoc entre guillemets écrit littéralement le JSON ; file:// permet à la CLI de le charger sans devoir protéger un gros contenu JSON avec des guillemets dans le shell. attribute_not_exists(order_id) n'autorise l'écriture que si aucun élément n'a cette clé. Le champ version: 1 est une valeur applicative que vous utiliserez pour protéger les mises à jour à l'étape 3 ; DynamoDB ne l'incrémente pas automatiquement.
cat > create-order.json <<'JSON'
{
"TableName": "labex-d04-orders",
"Item": {
"order_id": {
"S": "O100"
},
"amount": {
"N": "145"
},
"status": {
"S": "NEW"
},
"version": {
"N": "1"
}
},
"ConditionExpression": "attribute_not_exists(order_id)"
}
JSON
aws dynamodb put-item --cli-input-json file://create-order.json
aws dynamodb get-item \
--table-name labex-d04-orders \
--key '{"order_id":{"S":"O100"}}' \
--consistent-read
O100 contient le montant 145, NEW et la version 1. La condition d'absence est satisfaite pour cette nouvelle clé. Observez AWS View en haut et développez O100 pour inspecter l'élément réel.
Rejeter un doublon sans bloquer les nouvelles commandes
Dans cette étape, vous allez réutiliser un identifiant de commande avec un montant différent. Un écrasement non protégé ferait passer O100 à 999 ; la condition doit le rejeter et conserver 145. Un doublon rejeté produit une réponse d'erreur, pas automatiquement une réponse applicative idempotente réussie. L'application doit décider comment traiter cette erreur.
Une nouvelle tentative de création ne doit pas remplacer le montant déjà accepté pour une commande. La condition d’absence protège cette décision lors de l’écriture. Un filtre de lecture modifie les éléments retournés ; une condition d’écriture décide si la modification peut avoir lieu. Chaque requête concurrente doit porter sa propre condition.
Écrivez la requête concurrente avec la même clé et la même condition d'absence.
cat > duplicate-order.json <<'JSON'
{
"TableName": "labex-d04-orders",
"Item": {
"order_id": {
"S": "O100"
},
"amount": {
"N": "999"
},
"status": {
"S": "NEW"
},
"version": {
"N": "1"
}
},
"ConditionExpression": "attribute_not_exists(order_id)"
}
JSON
Répétez l'écriture avec la même clé. || true permet au terminal de continuer après cet échec attendu. Vérifiez la présence de ConditionalCheckFailedException ; une erreur de connexion ou d'autorisation nécessiterait un autre diagnostic.
aws dynamodb put-item --cli-input-json file://duplicate-order.json || true
aws dynamodb get-item \
--table-name labex-d04-orders \
--key '{"order_id":{"S":"O100"}}' \
--consistent-read
Attendez-vous à obtenir ConditionalCheckFailedException, puis le montant 145 et la version 1 inchangés. Prouvez que la même protection autorise un identifiant de commande différent, au lieu de refuser toutes les écritures.
cat > second-order.json <<'JSON'
{
"TableName": "labex-d04-orders",
"Item": {
"order_id": {
"S": "O101"
},
"amount": {
"N": "200"
},
"status": {
"S": "NEW"
},
"version": {
"N": "1"
}
},
"ConditionExpression": "attribute_not_exists(order_id)"
}
JSON
aws dynamodb put-item --cli-input-json file://second-order.json
aws dynamodb get-item \
--table-name labex-d04-orders \
--key '{"order_id":{"S":"O101"}}' \
--consistent-read
O101 est créée avec le montant 200, NEW et la version 1. AWS View affiche les deux commandes, tandis que le montant de O100 reste 145. Ces opérations empêchent un écrasement involontaire de cet enregistrement identifié par sa clé ; elles ne mettent pas en œuvre des transactions sur plusieurs éléments ni la déduplication des paiements.
Protéger une mise à jour avec la version attendue
Dans cette étape, vous allez appliquer une transition d'état uniquement à la version que vous avez lue. Une condition de version optimiste refuse une requête périmée au lieu d'écraser silencieusement une décision plus récente. L'écriture vérifie atomiquement la version 1, définit PAID et fait passer la version à 2.

Écrivez et exécutez cette requête UpdateItem. Les alias de noms d'expression permettent de manipuler les noms d'attributs en toute sécurité, et les valeurs typées fournissent la version attendue et la suivante.
cat > pay-order.json <<'JSON'
{
"TableName": "labex-d04-orders",
"Key": {
"order_id": {
"S": "O100"
}
},
"UpdateExpression": "SET #state = :paid, #version = :next",
"ConditionExpression": "#version = :expected",
"ExpressionAttributeNames": {
"#state": "status",
"#version": "version"
},
"ExpressionAttributeValues": {
":paid": {
"S": "PAID"
},
":next": {
"N": "2"
},
":expected": {
"N": "1"
}
},
"ReturnValues": "ALL_NEW"
}
JSON
aws dynamodb update-item --cli-input-json file://pay-order.json
ALL_NEW affiche PAID et la version 2 avec le montant 145. Rejouez la requête inchangée, qui attend toujours la version 1.
aws dynamodb update-item --cli-input-json file://pay-order.json || true
aws dynamodb get-item \
--table-name labex-d04-orders \
--key '{"order_id":{"S":"O100"}}' \
--consistent-read
Attendez-vous à obtenir ConditionalCheckFailedException. La lecture finale conserve PAID, la version 2 et le montant 145 ; O101 reste NEW/version 1. Un appelant en production relirait l'état courant et déciderait si une autre mise à jour est appropriée, au lieu de réessayer indéfiniment avec la version attendue périmée.

Supprimer uniquement la table de commandes de l'exercice
Dans cette étape, vous allez confirmer l'état final et nettoyer la table de l'exercice. Les fichiers JSON enregistrés décrivent les requêtes ; les éléments du service établissent leurs effets réels. N'utilisez pas l'historique des commandes ni un journal d'erreurs comme preuve de suppression de la table.
aws dynamodb scan --table-name labex-d04-orders --consistent-read
O100 a PAID/version 2/montant 145 ; O101 a NEW/version 1/montant 200. Supprimez uniquement cette table et attendez son absence.
aws dynamodb delete-table --table-name labex-d04-orders
aws dynamodb wait table-not-exists --table-name labex-d04-orders
aws dynamodb list-tables
aws dynamodb get-item \
--table-name labex-d04-reference \
--key '{"id":{"S":"platform"}}' \
--consistent-read
Seule la table de référence reste, avec la note keep unchanged. Ces requêtes réussies distinguent la suppression d'un échec de connexion. AWS View retire la table de commandes. La connexion temporaire prend fin avec cette VM.
Résumé
Vous avez protégé la création d'une commande avec une condition d'absence, observé le rejet d'un doublon sans modifier le montant stocké et autorisé une autre clé nouvelle. Vous avez ensuite utilisé une condition de version attendue pour appliquer une transition d'état et rejeter une répétition périmée. Vous avez inspecté les valeurs finales réelles des éléments avant de supprimer uniquement la table de l'exercice.
Pour approfondir ce sujet, consultez la documentation AWS : Expressions de condition pour écritures protégées.



