StrataDB uses Optimistic Concurrency Control (OCC) with snapshot isolation. Transactions read from a consistent snapshot and validate at commit time — no locks are held during execution.
How OCC Works
- Begin — the transaction takes a snapshot of the current state
- Read/Write — operations execute against the snapshot with read-your-writes semantics
- Validate — at commit time, StrataDB checks for conflicts with concurrent transactions
- Commit or Abort — if no conflicts, changes become visible; otherwise, the transaction aborts
This means:
- Reads never block. You always see a consistent snapshot.
- Writes never block other writers. Conflicts are detected at commit time, not at write time.
- Agents rarely conflict. In practice, agents working on different keys or different branches never conflict.
Using Transactions
Transactions are managed through the CLI’s begin, commit, and rollback commands:
$ strata --db ./data
strata:default/default> begin
OK
strata:default/default> kv put key 42
(version) 1
strata:default/default> kv get key
42
strata:default/default> commit
OK
Snapshot Isolation
Within a transaction, you see a consistent snapshot of the database as it was when the transaction began, plus your own writes:
- Read-your-writes: If you write a key, subsequent reads in the same transaction see your write.
- No dirty reads: You never see uncommitted changes from other transactions.
- No phantom reads: The set of keys matching a prefix doesn’t change during your transaction (from your perspective).
Conflict Detection
At commit time, StrataDB checks whether any key you read has been modified by another committed transaction since your snapshot was taken:
| Your Operation | Concurrent Operation | Conflict? |
|---|---|---|
| Read key A | Write key A | Yes |
| Write key A | Write key A | Yes (first committer wins) |
| Read key A | Write key B | No |
| Write key A | Read key A (other) | No (the other transaction will conflict if it tries to commit) |
| Blind write A | Blind write A | No (blind writes don’t add to read set) |
First committer wins: if two transactions write the same key, whichever commits first succeeds. The second gets a conflict error.
Transaction Scope
These operations route through the transaction when one is active:
| Primitive | Operations |
|---|---|
| KV | Get, Put, Delete, List |
| Event | Append, Read, Len |
| State | Read, Init, CAS |
| JSON | Set, Get, Delete |
These operations always bypass the transaction:
| Category | Operations |
|---|---|
| Vector | All vector operations |
| Branch | Create, Get, List, Exists, Delete |
| Database | Ping, Info, Flush, Compact |
Error Handling
When a transaction conflicts, you get a conflict error. In scripts, check exit codes and retry:
#!/bin/bash
set -euo pipefail
# Retry loop for transactional operations
for attempt in 1 2 3 4 5; do
strata --db ./data <<'EOF' && break
begin
kv get counter
kv put counter 1
commit
EOF
echo "Conflict on attempt $attempt, retrying..."
done
In the REPL, you can manually retry:
$ strata --db ./data
strata:default/default> begin
OK
strata:default/default> kv put key value
(version) 1
strata:default/default> commit
(error) TransactionConflict: key was modified by another transaction
strata:default/default> begin
OK
strata:default/default> kv put key value
(version) 1
strata:default/default> commit
OK
Auto-Rollback
If the CLI session ends (quit, Ctrl-C) while a transaction is active, the transaction is automatically rolled back. No uncommitted changes leak.
When to Use Transactions
| Scenario | Use Transaction? |
|---|---|
| Single key read or write | No — individual operations are already atomic |
| Read-modify-write on a key | Yes — prevents lost updates |
| Write to multiple keys atomically | Yes — all-or-nothing semantics |
| Cross-primitive consistency | Yes — KV + StateCell + EventLog in one atomic commit |
| Vector operations | No — vectors bypass transactions |
Next
- Durability — how data is persisted
- Sessions and Transactions Guide — full API walkthrough