Transaction use cases
Imagine two players both try to increment a counter at the same time. Without transactions:- Client A reads the counter:
10 - Client B reads the counter:
10 - Client A writes
11 - Client B writes
11
12, but it’s 11. One increment was lost. Transactions prevent this.
Callback-style transactions
The most common pattern. You provide a function that receives the current value and returns the new value. Lark handles the retry logic. Here’s what happens under the hood:- The SDK reads the current value at the path.
- Your function runs, receiving the current value and returning the new value.
- The SDK sends the new value to the server along with the value of the path that your client saw when it made the change.
- If another client changed the value between your read and write, the server rejects the transaction.
- Your function is called again with the updated value.
- This repeats until the write succeeds or the retry limit is reached (25 attempts).
undefined from your function to abort the transaction without writing anything.
Optimistic behavior
Transactions are optimistic by default. The client applies the result of your function to local state immediately, so your UI updates right away. If the server rejects the transaction and your function retries, the local state is updated again with the new result. This means your subscriptions fire immediately with the optimistic value, then potentially fire again if the server computes a different outcome. In practice, retries are rare and the optimistic value is almost always correct.Multi-path transactions
Sometimes you need to update multiple paths atomically, where either all the changes happen or none of them do. Multi-path transactions support two syntaxes:- Object syntax: Pass an object where keys are paths and values are what to write. Simple and concise for straightforward atomic writes.
- Array syntax: Pass an array of operations for more control, including the ability to add conditions.
Conditions (compare-and-swap)
In array-syntax transactions, you can addcondition operations that check the current value before proceeding. If any condition fails, the entire transaction is rejected and no writes are applied.
For primitive values (strings, numbers, booleans), the condition compares the value directly. For complex objects, to be efficient and avoid sending the entire object’s data over the wire, Lark computes a SHA-256 hash of the current value and compares that. This lets you condition on “this object hasn’t changed” without specifying every field. This is handled for you and you don’t need to worry about how calculating the hash yourself, but it’s useful to know how to works in the background.
Next steps
Lark SDK transactions
Full API reference and code examples for transactions in the Lark SDK.
REST API conditional requests
Compare-and-swap over HTTP using ETags.

