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.