DynamoDB Transactions, Conditional Writes and Optimistic Locking
SDK chapter showed light conditionals. Seoul commerce lead Minji Park still had double-booked seats because two Lambdas both passed a weak check. This chapter deepens TransactWrite/Get, condition expressions, optimistic locking and idempotency. Link: SDK DynamoDB.
What you'll learn in this chapter
- Explain with an everyday story
- Apply Why/What/How
- Read commands with output+meaning
- Map across industries
- Finish lab + cleanup
1. Everyday example: two cashiers one last chocolate
Two cashiers sell the last chocolate at once without talking — oversell. A transaction is both agreeing on one sale. A condition is "sell only if stock>0". Optimistic locking is writing a version number on the price tag and refusing stale updates.
2. Vertical steps
3. Why do we need this?
Why do we need this?
Concurrent writers corrupt stock, bookings and balances without atomic checks. Retries without idempotency create duplicates.
4. What is it?
What is it?
Conditional writes succeed only if expression true. Transactions group up to 100 actions all-or-nothing across items. Optimistic locking uses a version attribute. Idempotency keys make retries safe.
5. How to do it (step by step)
How to do it (step by step)
- Identify race-prone updates (stock, seats, balances).
- Add condition expressions (attribute_not_exists, version=).
- Use TransactWrite for multi-item invariants.
- Store IdempotencyKey for payment-like APIs.
- Handle TransactionCanceledException with reason codes.
6. Transaction sketch
TransactWriteItems: Update seat FREE->TAKEN; Put order item; condition on seat. Either both commit or neither.
7. Idempotency sketch
PK=IDEMP#key SK=META stores result. Put with attribute_not_exists(PK). Retries Get the stored result.
8. Commands with output and meaning
aws dynamodb put-item --table-name lab-dda-shop --item '{"PK":{"S":"SEAT#A1"},"SK":{"S":"META"},"status":{"S":"FREE"},"version":{"N":"1"}}'
aws dynamodb update-item --table-name lab-dda-shop --key '{"PK":{"S":"SEAT#A1"},"SK":{"S":"META"}}' \
--update-expression "SET #s = :taken, version = version + :one" \
--condition-expression "#s = :free AND version = :v" \
--expression-attribute-names '{"#s":"status"}' \
--expression-attribute-values '{":taken":{"S":"TAKEN"},":free":{"S":"FREE"},":v":{"N":"1"},":one":{"N":"1"}}'
# Output: success once. Second identical call fails ConditionalCheckFailedException.
# Meaning: only one booker wins; version bumps.
First update books FREE seat at version 1. Retry with stale version fails — optimistic lock + condition prevented double booking.
9. Industry stories
- Clinic (Meera Kulkarni, Pune): seat/slot booking conditions.
- Fintech (Elena Petrova): ledger lines in TransactWrite.
- Retail (Ananya Rao): stock decrement condition.
- Travel (Omar Haddad): room inventory transaction.
- Gaming (Carlos): claim reward once with attribute_not_exists.
10. Lab
How to do it (step by step)
- Put FREE seat; book with condition; replay book — expect failure.
- Optional: TransactWrite seat+order items.
- Delete lab data/table.
Cleanup (stop billing)
- Delete lab tables/indexes/triggers.
- Confirm describe-table fails or status missing.
11. Access-pattern workshop (paper first)
- List every screen or API that reads or writes data.
- For each: write the exact key lookup or query shape in plain English.
- Mark 1:1, 1:many, many:many relationships.
- Circle anything that needs a sort range (time, status, score).
- Only then invent PK/SK and optional GSI keys.
- Estimate peak items per partition key per second.
- Write one sample item JSON for each entity type.
- Peer-review with someone who did not design it.
12. Copy-paste DynamoDB CLI starters
# Region habit for this series
export AWS_DEFAULT_REGION=ap-south-1
# Describe + sample
aws dynamodb describe-table --table-name ShopApp
aws dynamodb scan --table-name ShopApp --max-items 3
# Query by PK (replace names)
aws dynamodb query --table-name ShopApp --key-condition-expression "PK = :pk" --expression-attribute-values '{":pk":{"S":"USER#u123"}}'
# On-demand capacity mode check
aws dynamodb describe-table --table-name ShopApp --query 'Table.BillingModeSummary'
# Streams status
aws dynamodb describe-table --table-name ShopApp --query 'Table.StreamSpecification'
13. More industry stories
- Retail (Aisha Khan, Dubai): single-table cart+orders; PK=USER#id keeps each shopper hot path local.
- Gaming (Carlos Rivera, Mexico City): leaderboard uses sparse GSI on score; write shard on hot gameId.
- IoT (Mei Lin, Shenzhen): sensor#day PK + timestamp SK; TTL 30 days keeps storage flat.
- Healthcare (Rohan Deshmukh, Pune): appointment slots use conditional Put — no double book.
- Fintech (Elena Petrova, Warsaw): Streams fan-out to audit table; never update audit in place.
- Travel (Omar Haddad, Amman): global tables for read-local catalog; writes region-sticky for inventory.
14. Glossary (short)
| Term | Meaning |
|---|---|
| PK / Partition key | Hash key that places the item in a partition |
| SK / Sort key | Orders items inside a partition; enables ranges |
| Item collection | All items that share the same PK |
| GSI | Global Secondary Index — alternate PK/SK, own partitions |
| LSI | Local Secondary Index — same PK, different SK |
| RCU / WCU | Read/Write Capacity Units on provisioned mode |
| Conditional write | Write succeeds only if a condition is true |
| Stream view type | KEYS_ONLY / NEW_IMAGE / OLD_IMAGE / NEW_AND_OLD_IMAGES |
15. Practice: explain out loud
- 60s: why access patterns come before table design.
- 60s: hot partition and one fix (write sharding).
- 60s: GSI vs LSI in one breath.
- 60s: on-demand vs provisioned for a startup.
- 60s: optimistic locking with a version attribute.
- 60s: Streams + Lambda for an audit trail.
- Record once; cut filler; record again.
16. Safe lab hygiene
- Use ap-south-1 labs with a budget alert (₹/USD).
- Prefix lab tables with lab- and your initials.
- Prefer on-demand for tiny labs unless you are learning auto scaling.
- Delete tables and Lambda triggers after the lab.
- Never point Streams consumers at production without a DLQ.
- Tag every resource Owner + Expiry.
17. How this set links other chapters
- What Is Amazon DynamoDB? — NoSQL vs RDS, first keys.
- CRUD, Query, Scan, GSI, TTL — basics we deepen, not copy.
- AWS CLI DynamoDB — command catalog.
- AWS SDK DynamoDB — SDK + light conditionals.
- Serverless project builds that *use* DynamoDB — we link, not rebuild.
18. Single-table sketch pad
Write entities as rows in one mental table before you open the console. Example for a small shop: USER#, ORD#, ORD#|ITEM#, PROD# under carefully chosen PK/SK.
| Entity | PK | SK | Example attrs |
|---|---|---|---|
| User | USER#u1 | PROFILE | name, city |
| Order | USER#u1 | ORD#2026-10-31#o9 | total, status |
| Order item | ORD#o9 | ITEM#sku1 | qty, price |
| Product | PROD#sku1 | META | title, stock |
19. Ten oral drill questions
- What is an access pattern?
- Why overload PK with entity prefixes?
- Name one hot-partition symptom.
- Sparse GSI means what?
- When is LSI impossible after create?
- On-demand bills for what?
- What does attribute_not_exists do?
- NEW_AND_OLD_IMAGES costs more — why still pick it?
- How do you stop a poison Streams message loop?
- Which existing chapter do you open for PutItem syntax?
20. Capacity and throttle drill
- Open CloudWatch for your table: ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits, ThrottledRequests.
- Note whether BillingMode is PAY_PER_REQUEST or PROVISIONED.
- If provisioned, write current RCU/WCU and autoscaling min/max.
- Name your hottest expected PK in one sentence.
- Write one mitigation: shard, cache, or redesign.
- Set or verify a budget alert for DynamoDB.
- Check GSI list and whether each is still used.
- Confirm Streams enabled only where consumers exist.
21. Condition expression cheatsheet
# Create-once
attribute_not_exists(PK)
# Optimistic lock
version = :v
# Stock / seat
stock > :zero
#status = :free
# Combine
attribute_not_exists(PK) AND #type = :user
Meaning: conditions are the seatbelt for concurrent writers. Put them on every race-prone update. Full SDK samples stay in the SDK chapter — here we only list the expressions you will reuse.
22. Streams consumer checklist
- View type matches need (KEYS_ONLY vs NEW_AND_OLD).
- Lambda has DLQ and retry policy.
- Handler idempotent on eventID or keys.
- IteratorAge alarm before users feel lag.
- No accidental write-loop back into the same table without markers.
- Fan-out via SNS/EventBridge when >1 consumer team.
- Disable stream when lab ends.
23. Link map for this deep set (batch 1)
- Ch1 Modeling -> Ch2 Hot keys -> Ch3 GSI/LSI -> Ch4 Capacity -> Ch5 Transactions -> Ch6 Streams.
- Always link intro + CRUD + CLI + SDK instead of rewriting Put/Get.
- Projects P1-P7 come in later batches and reuse these ideas.
24. Extra oral drills
- Explain single-table to a product manager in 45 seconds.
- Draw PK/SK for a chat thread on a whiteboard.
- Name three CloudWatch metrics for DynamoDB pain.
- Say when you would refuse a new GSI request.
- Describe one transaction for seat + payment record.
- Explain why Streams are at-least-once.
- Convert a Scan-based feature request into a Query design.
- List cleanup steps after a DynamoDB lab.
25. Teacher story: the notebook that became a database
Ravindra once watched a shop keep every customer, order and payment in one paper notebook. Finding last Tuesday's unpaid bills meant flipping pages. DynamoDB single-table thinking is that notebook done carefully: one place, clear labels (PK/SK), and an index tab (GSI) only when a second way to find rows is worth the cost. Do not photocopy the notebook into ten unrelated books unless the shop truly has ten separate businesses.
When Meera (clinic), Omar (travel), and Aisha (retail) design together, they still start on paper: screen list, key sketch, sample JSON, peer review. Console clicks come last. That ritual is why this deep series links the intro and CRUD chapters instead of rewriting PutItem on every page.
26. Sixteen mini tasks (self-check, leak-free)
- Write three access patterns for a cart app in one minute.
- Invent PK/SK for user profile and orders under that user.
- Name one hot-partition anti-pattern.
- Explain write sharding to a teammate in 40 seconds.
- Say GSI vs LSI without notes.
- Pick KEYS_ONLY or ALL for a sparse open-orders index — why?
- Choose on-demand or provisioned for a weekend flash sale.
- List five DynamoDB bill line-item types.
- Write a create-once condition in words.
- Describe optimistic locking with a version attribute.
- When do you wrap two writes in a transaction?
- Pick a stream view type for an audit log — justify.
- Name two Stream consumer safety rules.
- What CloudWatch metric shows stream lag?
- Which linked chapter has PutItem CLI syntax?
- Write your lab cleanup checklist (table, stream, lambda, alarms).
27. Marathi classroom lines (say out loud)
- Access patterns आधी, keys नंतर — हे mantra आठवा.
- Hot partition म्हणजे एक PK वर गर्दी — shard किंवा redesign.
- GSI लवचिक; LSI create-time — चुकीचा index महाग.
- On-demand म्हणजे वापरल्यावर पैसे; provisioned म्हणजे आरक्षित units.
- Condition आणि transaction म्हणजे race साठी seatbelt.
- Streams at-least-once आहे — handler idempotent ठेवा.
28. Hindi bridge lines
- Pehle access patterns likho, baad mein PK/SK.
- Hot partition ek key par zyada load.
- GSI kabhi bhi; LSI table banate waqt.
- On-demand spike ke liye; provisioned steady ke liye.
- Transaction = sab milkar ya kuch nahi.
- Streams duplicate de sakte hain — idempotent likho.
29. Common errors and fixes
Each row is a real mistake students and juniors hit. Read the fix before you panic.
| Error / symptom | Fix |
|---|---|
| Check-then-write without condition | Use condition/transaction. |
| Swallow ConditionalCheckFailed | Handle as expected conflict. |
| No version attribute | Add version. |
| Retry payment without idempotency key | Store key. |
| Transact across 200 items | Split design <=100. |
| Using transaction for single unconditional put | Simple Put enough. |
| Ignoring CancellationReasons | Log reasons. |
| Client clock for version | Use numeric version/etag. |
| Lost update on profile | Condition on version. |
30. Troubleshooting checklist
- ConditionalCheckFailed: another writer won — refresh and decide.
- TransactionCanceled: read CancellationReasons.
- ValidationException: too many actions.
- Idempotent retry returns prior result.
- Deadlock-like cancels: backoff.
31. FAQ
Q. Should I always use a single table?
Often yes for related access patterns; not a religion. Separate tables are fine for unrelated domains or different capacity/security needs.
Q. Do I still need RDS?
Yes for heavy joins, multi-row SQL reports, and strong relational constraints. See the intro DynamoDB vs RDS chapter.
Q. Is Scan evil?
Scan is a tool for rare admin jobs and small tables. Design so hot paths use Query/GetItem.
Q. Where are Put/Get command details?
In the CRUD survey, CLI and SDK chapters — this deep set links them instead of copying.
Q. Optimistic locking?
Version attr; write only if version matches.
Q. TransactWrite?
All-or-nothing multi-item write.
Q. attribute_not_exists?
Succeeds only if attr missing (create-once).
Q. Idempotency key?
Client key stored so retries do not double-apply.
32. Interview Q&A
Q. (B) Why conditions?
Prevent lost updates / double book.
Q. (B) ConditionalCheckFailed meaning?
Condition false — conflict.
Q. (M) Optimistic vs pessimistic?
Version retry vs locks; DynamoDB uses conditions.
Q. (M) Transaction limits?
Up to 100 actions; 4MB etc.
Q. (S/MNC) Payment API design?
Idempotency key + conditional ledger + DLQ.
Q. (MNC) Double-booking RCA?
Show missing condition on seat item.
33. Tips in English, Marathi and Hindi
Ravindra Bagale's Tip (EN)
If two writers can touch it, write a condition.
Ravindra Bagale's Tip (MR)
दोन writers = condition.
Tip (HI)
दो writer हों तो condition लिखो।
Try at home
- Find one race in your app; write a condition.
- Add a version attr on paper.
- Skim SDK conditional section.
In short
- Conditions stop races.
- Transactions for multi-item invariants.
- Version = optimistic lock.
- Idempotency for safe retries.
Revision, interview and comparison cards
Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.








More cards: Ravi Sir's Cards.
Practice Tasks
Milan Furniture is a furniture business in Milan. Giulia Rossi looks after its IT and cloud work. They count money in EUR and run their AWS resources in the eu-south-1 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.
0 / 16
Easy TransactWrite is all-or-nothing — 1
Why: Atomic.
What to do: Enter 1 if TransactWriteItems is all-or-nothing across its actions.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy Condition must be true — 1
Why: Gate.
What to do: Enter 1 if a conditional write succeeds only when the condition is true.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy Optimistic lock uses version — 1
Why: Lock.
What to do: Enter 1 if optimistic locking often checks a version attribute.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy attribute_not_exists for create-once — 1
Why: Insert.
What to do: Enter 1 if attribute_not_exists(PK) is a create-once pattern.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Easy Condition names YAML
Why: List.
What to do: YAML list conds with attribute_not_exists and version.
- Start from the top-level keys the task names.
- Indent child keys with 2 spaces (no tabs).
- Fill in each property with the value from the task.
- Click Check answer. Key order does not matter.
Easy Describe table before txn lab
Why: CLI.
What to do: Describe table ShopApp
- Read the task and decide which AWS service it is about.
- Write aws, then the service name, then the operation (the action word).
- Add each needed flag (--name) followed by its value from the task.
- Flags can be in any order. Click Check answer.
Easy Partial txn success should not commit — 1
Why: Property.
What to do: Enter 1 if a failed condition should fail the whole transaction.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Idempotency helps retries — 1
Why: Retry.
What to do: Enter 1 if idempotency tokens make retries safer.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Canceled txn check reasons — 1
Why: Debug.
What to do: Enter 1 if transaction canceled often means checking CancellationReasons.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium SDK chapter has light conditionals — 1
Why: Depth.
What to do: Enter 1 if the SDK chapter covers light conditionals and this goes deeper.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium TransactGetItems for transactional reads — 1
Why: Read.
What to do: Enter 1 if TransactGetItems performs transactional reads.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Medium Booking flow YAML
Why: Flow.
What to do: YAML: check: seat-free, write: mark-taken.
- Start from the top-level keys the task names.
- Indent child keys with 2 spaces (no tabs).
- Fill in each property with the value from the task.
- Click Check answer. Key order does not matter.
Hard Seat booking uses conditions — 1
Why: Pattern.
What to do: Enter 1 if seat booking uses a condition that the seat is free.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Know the 100-action limit — 1
Why: Limit.
What to do: Enter 1 if transactions have an action-count limit you must design within.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard Race-prone updates need conditions — 1
Why: Safety.
What to do: Enter 1 if race-prone updates should carry condition expressions.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.
Hard stock > :zero style checks — 1
Why: Expr.
What to do: Enter 1 if stock or seat checks often use comparison conditions.
- Write down the numbers the task gives you.
- Work it out step by step on paper.
- Type only the final answer in the box.
- Click Check answer.