Concurrency, isolation and durability
ParticleDB has three independent settings: transaction isolation (what a transaction reads), concurrency control (how conflicts between concurrent transactions are detected) and durability (when a commit is on disk). Each is configured separately; changing one does not change the others.
Transaction isolation levels
Section titled “Transaction isolation levels”Default: READ COMMITTED (--default-isolation read-committed), as in PostgreSQL.
| Level | What the application observes |
|---|---|
| READ COMMITTED (default) | Each statement sees data committed before that statement began |
| REPEATABLE READ | Snapshot isolation: the whole transaction reads one snapshot, and write conflicts are refused at commit |
| SERIALIZABLE | Read and predicate dependencies are validated, so the result matches some serial order |
Change the server default with --default-isolation read-committed|repeatable-read|serializable. A session or transaction chooses its own level:
BEGIN ISOLATION LEVEL SERIALIZABLE;SHOW transaction_isolation;COMMIT;
-- change the default for later transactions on this connectionSET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;Keep all of a transaction’s statements on one connection. Choose the level at BEGIN (or through the client’s transaction API), or with SET TRANSACTION before its first query. Changing the session default does not upgrade a transaction that is already running.
Concurrency control: --concurrency-control
Section titled “Concurrency control: --concurrency-control”Default: optimistic. This server-wide setting selects how conflicts between concurrent transactions are detected.
| Name | What it does | Default isolation level |
|---|---|---|
optimistic (default) |
Checks for conflicts when a transaction commits, according to its isolation level | READ COMMITTED |
strict-optimistic |
Everything optimistic does, with stricter reads, recovery and autocommit handling, so SERIALIZABLE also guarantees real-time order |
READ COMMITTED |
none |
No conflict checks. Concurrent writers can lose each other’s updates. For bulk loads and single-writer ingest only | READ COMMITTED |
particledb start --concurrency-control optimistic --data-dir ./pdb-dataWhat to expect in each concurrency-control mode
Section titled “What to expect in each concurrency-control mode”optimistic (default)
Section titled “optimistic (default)”Conflict validation at commit. Recommended for general application workloads.
| Isolation level | What to expect |
|---|---|
| READ COMMITTED (default) | Each statement sees data committed before it began. Some conflicting updates are re-applied to the latest committed row by the server; any other conflict fails the commit with SQLSTATE 40001 |
| REPEATABLE READ | Snapshot isolation. A write conflict fails the commit with 40001 |
| SERIALIZABLE | Serializable: a commit that no serial order could produce fails with 40001. Real-time order held in every test but is not guaranteed by construction, because reads may fall back to an older row copy |
When the server returns 40001 (serialization_failure), roll back and retry the complete transaction with a bounded policy, and keep external actions idempotent. Internal re-application does not remove the need for retry handling.
strict-optimistic
Section titled “strict-optimistic”optimistic validation plus authoritative committed reads, strict recovery and durable-before-visible autocommit writes. Required for strict serializability.
| Isolation level | What to expect |
|---|---|
| READ COMMITTED (default) | Same as optimistic. An explicit READ COMMITTED transaction is never upgraded |
| REPEATABLE READ | Snapshot isolation, as in optimistic |
| SERIALIZABLE | Strict serializable: serializable plus real-time ordering, guaranteed by construction |
Also server-wide: reads never fall back to an older row copy, startup refuses an incomplete recovery, autocommit writes become visible only once they are durable (when WAL logging is on), and unlabelled autocommit SKIP LOCKED claims and predicate UPDATEs run strict serializable.
No conflict validation. Bulk loads and single-writer ingest of reproducible data only.
| Isolation level | What to expect |
|---|---|
| READ COMMITTED (default) | Accepted. No isolation guarantee: without conflict validation, concurrent writers can lose updates without an error |
| REPEATABLE READ | Refused with SQLSTATE 0A000 (feature_not_supported) |
| SERIALIZABLE | Refused with SQLSTATE 0A000 (feature_not_supported) |
The refusal applies in every form, including --default-isolation at startup. Do not use it with concurrent writers. It does not disable the write-ahead log; durability is configured separately.
Statements outside an explicit transaction
Section titled “Statements outside an explicit transaction”An explicit BEGIN with no isolation clause uses the session or server default. Unlabelled autocommit statements can follow the server’s concurrency-control setting, as described for strict-optimistic; an explicitly selected session isolation level takes precedence. For business rules spanning several statements, use an explicit transaction with an explicit level.
Durability: --durability
Section titled “Durability: --durability”Default: groupsync.
| Name | How it works | What to expect after a crash |
|---|---|---|
groupsync (default) |
COMMIT returns after the commit’s WAL record is flushed to disk. Commits that arrive together share one flush | Every acknowledged commit survives |
sync |
COMMIT returns after the commit’s own flush to disk | Every acknowledged commit survives |
none |
COMMIT returns immediately. The write-ahead log is off | Nothing: acknowledged commits are lost on any restart, even a clean shutdown, and there is no crash recovery |
groupsync and sync give the same guarantee; groupsync is faster under concurrency because one flush covers many commits. none is refused with replication; use it only for data you can recreate.
On macOS a flush may not empty the drive’s cache, so a power loss can still lose recently acknowledged commits there. Use a durable setting for application records and test recovery on your actual platform and storage. See durability and restart.
KV durability: --kv-durability
Section titled “KV durability: --kv-durability”Default: async. This applies to KV commands on the Redis-compatible endpoint; KV writes over the native PDB wire always follow --durability.
| Name | How it works | What can lose an acknowledged write |
|---|---|---|
async (default) |
A KV write is acknowledged once its WAL bytes reach the operating system | An OS crash or power loss can lose recent acknowledgements. A process crash loses nothing acknowledged |
sync |
A KV write is acknowledged after the flush to disk | Only failures outside the --durability guarantee |
The default falls back to sync (with a log line) under --durability none, a striped WAL (--num-wal-stripes above 1) or replication. An explicit --kv-durability async in those configurations is refused. At runtime, CONFIG SET pdb-kv-durability sync|async on the Redis-compatible endpoint changes the setting until the next restart.
Experimental modes (not in current release builds)
Section titled “Experimental modes (not in current release builds)”The modes below were experimental. They appeared only in pre-release builds before 1.1.19-rc.13, under that build’s --txn-mode flag, including the builds examined in the Jepsen analysis of ParticleDB, and were never a supported configuration. None of them is in current release builds. Independent testing of those builds found safety errors in them. Each name now fails at startup with Error: invalid --concurrency-control '<name>', exit code 1, and the list of accepted values.
| Removed name | What it was | Use instead |
|---|---|---|
occ-v3, occv3, occ-v2, occv2, serializable-occ |
Earlier names of the optimistic engine | optimistic |
zero-copy-occ, zcocc |
Experimental partition-pinned variant of the optimistic engine | optimistic |
table-2pl, 2pl, row-2pl, row_2pl |
Experimental table-lock engine; by the time it was removed it no longer used two-phase locking | strict-optimistic |
serializable-ssi, ssi |
Experimental serializable snapshot isolation engine | strict-optimistic |
strict-serializable, strict-ser |
Earlier name of strict serializable mode | strict-optimistic |
In some pre-release builds, serializable was itself an alias of table-2pl; the current strict-optimistic is a different, newer mode. Removing a name does not change findings about the builds that accepted it. If you ran a pre-release build, upgrade, choose one of the current modes above, and check your data against a trusted source. See release history.
Related
Section titled “Related”Transactions · Durability and restart · Coordinate concurrent updates · CLI reference