Skip to main content
Transactions let you update data based on its current value without worrying about conflicts from other clients. They’re essential for counters, inventory systems, auctions, and any scenario where a write depends on the existing data. For a conceptual overview of how transactions work and why you need them, see Transactions.

Callback-style transactions

The most common pattern. Pass a function that receives the current value and returns the new value:

Transaction results

Every transaction() call returns a result object:

Aborting a transaction

Return undefined from your update function to abort without writing:

Retry limit

Transactions automatically retry up to 25 times. If they still can’t commit after 25 attempts (due to extremely high contention), the promise rejects with a max_retries_exceeded error.
Your update function may be called multiple times if there are concurrent writes. Make sure it has no side effects. Don’t make network requests, modify external state, or log analytics inside it.

Multi-path transactions

When you need to update multiple paths atomically, either all the changes happen or none of them do.

Object syntax

The simplest form. Pass an object where keys are paths and values are what to write. Use null to delete a path.
All three writes happen atomically. If any one fails, none of them are applied.

Array syntax with conditions

For more control, use the array syntax with explicit operations. This lets you add conditions that check the current value before proceeding.
If any condition fails, the entire transaction is rejected and no writes are applied. You can also pass a snapshot of a complex object as a condition. Internally, the LarkJS library will compute a hash representing the state of this object and pass it as the condition to the server, keeping the transaction efficient (so the entire object isn’t sent).

Examples

Increment a counter

Update a high score (only if higher)

Transfer currency between players

Claim a unique resource

Use a transaction to ensure only one client can claim something:

Conditional multi-path update

Only claim a reward if it hasn’t been claimed yet:
Avoid running transactions on paths with very high write contention from many clients simultaneously. If you’re hitting the retry limit frequently, consider restructuring your data to reduce contention. For example, you could shard counters across multiple paths.