Transactions are serializable by default. Live queries only ever show committed data, and their results always match a fresh run of the query.
Live Queries
- Every update is a committed state. A subscriber never sees a partial transaction or a write that later rolls back.
- Updates match a fresh query. Applying the changes you receive, in order, gives exactly the result of running the query from scratch at that point.
- Updates move forward. A subscription never goes back to an older state. Rindle may combine several commits into one update, so you can skip intermediate states, but you never see a state that didn’t exist.
- An open transaction is invisible. Its writes appear in live queries when it commits, all at once.
Isolation
| Level | Guarantee | Default for |
|---|---|---|
serializable |
The result is the same as if transactions ran one at a time, in some order. | Read-write transactions |
snapshot |
Each transaction reads one consistent snapshot, from when it began, and two transactions conflict only if they write the same row. A rule that spans rows, such as “at least one admin”, can be broken by two concurrent transactions (write skew). | Read-only transactions |
Single statements and batches are each one transaction. Interactive transactions choose a level
when they begin (POST /db/transactions).
Transactions never wait for each other. Each one reads its own snapshot, and Rindle checks it at
commit. If a concurrent commit means it can’t be serialized, the commit fails with
409 TRANSACTION_CONFLICT and nothing is written. Run the whole transaction again from its first
statement. Rindle doesn’t retry for you, because only your code knows whether the transaction
still makes sense.
Within a transaction you see your own writes. Outside it, a read sees the latest committed state.
Durability
A write is committed when its request returns. What survives depends on what fails:
| Failure | Default (commitSync: "normal") |
commitSync: "full" |
|---|---|---|
| Process crash | Nothing lost | Nothing lost |
| Power loss | Commits since the last checkpoint may be lost | Nothing lost |
| Machine lost | Up to the last 60 seconds of commits may be lost | Up to the last 60 seconds of commits may be lost |
The database is never left corrupt or half-applied. A recovered database is always some committed state.
Rindle ships its log to object storage continuously and can restore to any commit in the retention window. Closing the 60-second window for a lost machine is the main remaining work; see Status.
Followers
All writes and SQL reads go to the leader, so they always see the latest commit. Live queries run on followers, which apply the leader’s commits in order, usually within milliseconds. A subscription reflects a commit once its follower has applied it.