Skip to content

Transaction Engine

ParticleDB’s transaction behavior is controlled by two server-start choices:

  • --wal-sync-mode decides durability cost (sync, groupsync, nosync)
  • --txn-mode decides concurrency behavior (fast, occ-v3, serializable-ssi, strict-serializable, table-2pl)

The codebase no longer has a single always-on “serializable snapshot isolation” path. Instead, the engine exposes several operational modes so you can choose between maximum throughput and stronger safety.

The write-ahead log persists mutations before they become durable.

ModeBehaviorTypical use
syncfsync on each commitStronger durability, lower throughput
groupsyncBatch fsync via group commitGeneral production default
nosyncSkip explicit fsyncBenchmarks, reloadable data, ephemeral environments
Terminal window
particledb start --wal-sync-mode sync
particledb start --wal-sync-mode groupsync
particledb start --wal-sync-mode nosync

If --txn-mode is omitted, ParticleDB picks occ-v3 by default. When --wal-sync-mode sync is set, the default switches to table-2pl for the strictest semantics.

Transaction mode is selected at server start, not with PostgreSQL SERIALIZABLE session syntax.

Terminal window
particledb start --txn-mode fast
particledb start --txn-mode occ-v3
particledb start --txn-mode serializable-ssi
particledb start --txn-mode strict-serializable
particledb start --txn-mode table-2pl
ModeBehaviorNotes
fastMinimal coordination, highest OLTP throughputBulk loads, single-writer benchmarks — no isolation guarantees
occ-v3Buffered writes plus commit-time write-set validation, MVCC snapshot readsGeneral OLTP — safe under concurrency (default)
serializable-ssiAdaptive serializable snapshot isolation (PL-3)Serializable workloads that want optimistic concurrency (alias: ssi)
strict-serializableSerializable-SSI plus real-time (linearizable) orderingStrongest guarantee (alias: strict-ser)
table-2plExclusive table locksStrict serialization via locking, lowest concurrency (alias: 2pl)

The following names are accepted as deprecated aliases that map to occ-v3: occ, occ-v2, zero-copy-occ, zcocc, serializable-occ, row-2pl. The removed serializable mode is rejected with an error directing you to serializable-ssi or occ-v3.

Within an open transaction, mutations are buffered before commit:

  • INSERT, UPDATE, and DELETE are collected in a transaction buffer
  • reads merge the base snapshot with the transaction overlay
  • COMMIT replays buffered operations
  • ROLLBACK discards them

That overlay is what allows statements later in the same transaction to see rows inserted or updated earlier in the same transaction.

The core lifecycle is standard:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

Two-phase commit is also implemented:

BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE id = 1;
PREPARE TRANSACTION 'transfer_tx_001';
COMMIT PREPARED 'transfer_tx_001';
-- or
ROLLBACK PREPARED 'transfer_tx_001';

ParticleDB parses and executes the common PostgreSQL row-locking forms:

  • FOR UPDATE
  • FOR SHARE
  • NOWAIT
  • SKIP LOCKED

Example:

BEGIN;
SELECT *
FROM jobs
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED;
COMMIT;

The finer PostgreSQL lock modes FOR NO KEY UPDATE and FOR KEY SHARE are not part of the current implementation.

ParticleDB does not currently honor PostgreSQL SERIALIZABLE requests over PG wire. The server explicitly rejects that setting and tells clients to use read committed.

In practice:

  • choose the engine behavior with --txn-mode
  • use normal BEGIN / COMMIT / ROLLBACK in clients
  • do not rely on SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
  • SAVEPOINT, RELEASE SAVEPOINT, and ROLLBACK TO SAVEPOINT are supported
  • Use groupsync + occ-v3 or groupsync + table-2pl when you want a safer baseline.
  • Use nosync + fast only when you can tolerate data loss on crash.
  • Use --oltp-partitions for warehouse-affine OLTP workloads such as TPC-C.
  • Keep transactions short so buffered writes and lock hold times stay small.