dynobase-icon
Dynobase

DynamoDB Locking: Optimistic and Pessimistic Approaches

Lakindu Hewawasam

Written by Lakindu Hewawasam

Last updated: October 23rd, 2026

Working with DynamoDB every day? Dynobase is a desktop DynamoDB client for macOS, Windows and Linux for browsing, querying and editing your tables. Try it free for 7 days. Learn more

DynamoDB optimistic locking uses a version attribute and a conditional write to reject changes based on stale data. For an explicit acquire-and-release lock, use an application-level lease, such as the Amazon DynamoDB Lock Client. Transactions provide atomic changes across items, but they do not hold a lock while your application reads data, waits for a user, or calls an external service.

Introduction to DynamoDB locking

A single DynamoDB write is atomic. The concurrency problem appears when an application reads an item, computes a new value, and writes later: another writer can change the item between those requests. An unconditional replacement can then discard that writer's work.

For example, two editors read version 3 of a note. Both submit a different revision. If each write requires version 3 and changes the version to 4, only one can succeed. The other editor receives a conflict instead of silently overwriting the first edit.

Not every update needs a version. An atomic counter or a condition such as sufficient inventory can express the rule directly in one request. Start with the smallest conditional write that protects the business invariant.

Optimistic locking

What is optimistic locking?

Optimistic locking detects competing edits when you save. Readers do not reserve the item or block other readers. The application carries the version it read and includes that expected version in the write's ConditionExpression.

Use an integer version that changes on every accepted edit. A timestamp is useful audit metadata, but a wall-clock timestamp can repeat or move backward. It is a poor default concurrency token when several writers can update within the same clock tick.

How does optimistic locking work?

  1. Create the item with a version, using a create-only condition.
  2. Read the item and retain its version with the editable data.
  3. Save changes only if the stored version still equals that value.
  4. Increment the version in the same write.
  5. On ConditionalCheckFailedException, reload or show a conflict. Reapply the business decision to fresh data before trying again.

A strongly consistent read reduces the chance of starting with stale data, but it cannot prevent another writer from changing the item afterward. The write condition is what prevents a lost update.

How to use optimistic locking with SDK v3

Create the example notes table with a string partition key named note-id:

The following JavaScript uses the v3 document client. Run the initialization once; its condition intentionally rejects subsequent attempts to create the same note.

To exercise the conflict path, run two reads before either update, then submit both writes with the same expected version. Alternatively, pass a deliberately stale version. Do not make the production code silently replace :expected with the latest version while retaining an old full-item edit.

Example terminal output showing a conditional-check failure for a stale note

An accepted write advances the version. Another request with the old version now fails, including one that tries to delete the item if you apply the same condition to DeleteItem.

Example terminal output confirming a successful note update

The same version check with boto3

This function takes the version the editor originally read. It returns the saved note or raises the conflict for the caller to handle.

ReturnValuesOnConditionCheckFailure can return the item that caused the condition to fail, saving a separate diagnostic read. Its response representation depends on the SDK interface, so inspect the error shape before treating it as a native object.

Java 2.x Enhanced Client version attributes

For new Java applications, use the DynamoDB Enhanced Client and @DynamoDbVersionAttribute. Its default VersionedRecordExtension adds the version checks and increments for supported writes. A mapped bean for the same table can declare:

The extension starts newly versioned items at 0 by default and increments by 1; both are configurable. Read the bean through the Enhanced Client, retain its version, modify it and call the mapped table's updateItem. If you configure custom extensions, explicitly retain VersionedRecordExtension, because custom extension configuration replaces the defaults.

The annotation does not automatically protect deleteItem; supply your own delete condition. AWS documents these behaviors in Enhanced Client extensions.

@DynamoDBVersionAttribute, with a capital DB, belongs to the legacy Java 1.x DynamoDBMapper. It is not the Java 2.x annotation. A migration should check save and delete behavior rather than only rename the import.

Benefits and limits of optimistic locking

Optimistic locking is a good fit for editable forms and other read-modify-write workflows with occasional conflicts. It needs no lease table or heartbeat, and readers proceed normally. Under heavy contention, repeated failed conditions cost capacity and application work; an atomic expression, queue or different data model may be more useful than retrying every collision.

Every writer must follow the protocol. A script that replaces an item without checking or advancing its version can invalidate the guarantee. Also plan for deletion and recreation: reusing the same key and resetting its version can make a very old edit look current. A separate immutable generation identifier can distinguish those lifetimes.

Pessimistic locking

What is pessimistic locking?

An application-level pessimistic lock reserves a resource before work begins. All participants agree to acquire the lock first and release it afterward. DynamoDB does not expose a SQL-style SELECT FOR UPDATE session that you keep open while your application works.

This is useful for coordinating a job or an external resource. A lock item does not automatically block ordinary writes to another DynamoDB item; every participating writer must honor it.

Amazon DynamoDB Lock Client: current status

The Amazon DynamoDB Lock Client is a Java library, with AmazonDynamoDBLockClient as its main class. Checked on October 23, 2026, the repository is not archived, its README describes community support, and its current examples use the AWS SDK for Java 2.x. These observations do not imply an AWS support SLA or a release cadence.

AWS's distributed locking guidance still points to this library. That guidance does not name a replacement lock client. The Enhanced Client replaces DynamoDBMapper for object mapping; it is not a successor to this distributed locking library.

How lease-based locks work

The lock owner acquires a resource key with a conditional write, renews ownership through heartbeats, and releases it in a finally block. A contender can take over when the lease protocol establishes that the previous owner stopped renewing.

The Java client's README describes a record-version token and elapsed lease observation, rather than relying on deletion of a TTL attribute. A custom absolute-expiry design must separately account for clock skew. In either design, renewal and release must verify ownership, so a delayed old worker cannot renew or delete a new owner's lock.

Time to Live is optional cleanup for expired lock records in a custom design. Deletion typically happens within a few days, so waiting for the item to disappear would turn a short lease into a long outage. Evaluate lease expiry in the acquisition condition and keep the TTL cleanup deadline separate if the protocol needs longer-lived records.

A paused worker may resume after its lease has expired. Stop work when renewal fails and use fencing where the protected resource supports it: the resource rejects operations carrying an obsolete ownership generation. Lock acquisition alone cannot make an external side effect exactly once.

Benefits and tradeoffs of pessimistic locks

Locks can reduce duplicate work when recomputing a long operation is expensive. They also add acquisition latency, heartbeat costs and failure recovery. Keep the protected section short, establish a consistent acquisition order if you need multiple locks, and monitor renewal failures and time spent waiting.

High contention does not automatically make leases the right answer. A single highly contested lock serializes every caller. A queue or partitioned ownership may fit the workload better.

Transactions are an alternative, not a held application lock

Use TransactWriteItems when several DynamoDB changes must commit together. Put the expected version or state condition directly on the transaction's update. A transaction without that condition does not know which earlier read your application used.

For a note revision plus an audit record, transact an update of the current note and a put of a distinct audit item. If the version condition fails, neither change commits. Transaction conflicts remain possible and need handling; transactions do not eliminate conflicts or hold a reservation between requests.

Multi-Region eventual-consistency global tables reconcile concurrent writes using last-writer-wins behavior, so local version conditions do not provide a cross-Region lock. Route a lock authority to one Region or design a protocol for your selected consistency mode. MRSC global tables support strongly consistent cross-Region reads but do not support transactions or TTL.

Optimistic vs pessimistic locking: what should you use?

RequirementStarting point
Reject an editor's stale changesVersion condition
Increment a counter or change one item based on its current stateAtomic UpdateItem expression, with a condition where needed
Commit related changes to several itemsTransaction with explicit business conditions
Coordinate a long-running task or external resourceLease-based lock with renewal, ownership checks and stale-owner handling
Retain every historical revisionAn explicit version-history model

Frequently Asked Questions

Does DynamoDB have locking by default?

Individual writes are atomic, but DynamoDB does not automatically protect an application's read-modify-write sequence. Add a condition, transaction or application lease according to the invariant you need.

How does DynamoDB optimistic locking work?

Read a version with the item, then condition the write on that version and increment it in the same request. A stale version causes ConditionalCheckFailedException.

Is TransactWriteItems a pessimistic lock?

It provides atomic multi-item writes, not a lock held across separate application requests. Include conditions if the writes depend on previously read values.

Can TTL release a DynamoDB lock on time?

No. TTL cleanup is asynchronous and typically takes a few days. A lease protocol must decide ownership independently of physical deletion.

Is the Amazon DynamoDB Lock Client deprecated?

The repository was not archived when checked on October 23, 2026, and AWS still documents it. Its README describes community support; evaluate dependencies and maintenance before adopting it.

Dynobase is a Professional GUI Client for DynamoDB

Start your 7-day free trial today

Product Features

Download
/
Pricing
/
Member Portal
/
Privacy
/
EULA
/
Twitter
© 2026 Dynobase