Skip to content
Quest 12Advanced20 min

Catching Lugia (Conditional Writes)

You've encountered Lugia, the Guardian of the Seas! You throw a Master Ball, but what if another trainer threw one at the exact same millisecond? We don't want two trainers owning the exact same legendary instance in the database.
Start the lesson

What you'll learn

  • Condition Expressions enforce rules before writing to DynamoDB.
  • UpdateItem can create a new item, so also assert that the target key exists.
  • Conditional checks occur server-side, preventing race conditions.

Section 01

Safe Legendary Catches

By adding a ConditionExpression to our UpdateItem call, we can tell DynamoDB: "Only assign ownership if this Lugia exists and has no owner." If someone else caught it a millisecond earlier, the condition fails and DynamoDB throws a ConditionalCheckFailedException.

Conditional WriteJavaScript
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, UpdateCommand } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({ region: "ap-south-1" });
const docClient = DynamoDBDocumentClient.from(client);

await docClient.send(new UpdateCommand({
  TableName: "LegendaryPokemon",
  Key: { Name: "Lugia" },
  UpdateExpression: "SET #own = :trainer",
  ConditionExpression: "attribute_exists(#name) AND attribute_not_exists(#own)",
  ExpressionAttributeNames: { "#name": "Name", "#own": "Owner" },
  ExpressionAttributeValues: { ":trainer": "Ash" }
}));
AshAWS SDK v3GaryAWS SDK v3DynamoDBtableP0P1P2P3CONSUMED0

Ready · 9 steps · Orbi

This animation plays when you scroll to it. Press Play to start it now.

All steps as text
  1. Trainer Ash sends UpdateItem to the JohtoPokemon table with Name = "Lugia". No ConditionExpression: SET #own = :trainer
  2. DynamoDB hashes "Lugia" to 96f9f356, which routes the request to partition P2.
  3. P2 updates Lugia (Owner → Ash).
  4. This call consumed 1 WCU.
  5. DynamoDB responds with success: Ash caught Lugia.
  6. Trainer Gary sends UpdateItem to the JohtoPokemon table with Name = "Lugia". No ConditionExpression: SET #own = :trainer
  7. DynamoDB hashes "Lugia" to 96f9f356, which routes the request to partition P2.
  8. Trainer Gary's write to Lugia lands on P2 and silently replaces the other change.
  9. DynamoDB responds with success: both trainers were told they caught Lugia.

Practice

Your turn

Two trainers might throw a Master Ball at the same instant. Make the catch safe by only writing the Owner if Lugia has no owner yet.
Require attribute_exists(#name), with #name mapped to Name and attribute_not_exists(#own). This prevents both duplicate ownership and a phantom item if Lugia's key does not exist.
Tab inserts two spaces. Press Escape, then Tab, to leave the editor. Control or Command plus Enter runs the code.
Simulated — no AWS calls

Check

Check your understanding

Quick Quiz · one question, as many tries as you need.

What DynamoDB function checks if an attribute is missing before allowing a write?

Choose one answer.