Transactions
ParticleDB supports explicit transactions with BEGIN, COMMIT, and ROLLBACK, plus two-phase commit with PREPARE TRANSACTION. The exact concurrency behavior depends on the server’s --txn-mode; see the Transaction Engine page for engine-level details.
Quick Start
Section titled “Quick Start”BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;If anything goes wrong:
BEGIN;DELETE FROM important_data WHERE created_at < '2024-01-01';ROLLBACK;Core Statements
Section titled “Core Statements”BEGIN;BEGIN TRANSACTION;COMMIT
Section titled “COMMIT”COMMIT;COMMIT TRANSACTION;ROLLBACK
Section titled “ROLLBACK”ROLLBACK;ROLLBACK TRANSACTION;Auto-Commit
Section titled “Auto-Commit”Without an explicit BEGIN, each statement runs in its own auto-committed unit:
INSERT INTO logs (message) VALUES ('event 1');INSERT INTO logs (message) VALUES ('event 2');Savepoints
Section titled “Savepoints”Savepoints are supported for partial rollback inside an open transaction:
SAVEPOINT name— capture the transaction’s current state under a nameROLLBACK TO SAVEPOINT name— discard writes made after the named savepoint (and remove any savepoints established after it), keeping the transaction openRELEASE SAVEPOINT name— forget the named marker without rolling back its writes
BEGIN;INSERT INTO logs (message) VALUES ('event 1');SAVEPOINT sp1;INSERT INTO logs (message) VALUES ('event 2');ROLLBACK TO SAVEPOINT sp1; -- 'event 2' is discarded, 'event 1' remainsCOMMIT;Savepoints must be issued inside a transaction block (otherwise the server returns 25P01), and there is a per-transaction cap on the number of active savepoints.
Two-Phase Commit
Section titled “Two-Phase Commit”Prepared transactions are implemented:
BEGIN;UPDATE accounts SET balance = balance - 500 WHERE id = 1;PREPARE TRANSACTION 'transfer_tx_001';Then later:
COMMIT PREPARED 'transfer_tx_001';-- orROLLBACK PREPARED 'transfer_tx_001';Useful properties of the current implementation:
- prepared transaction IDs must be unique
- prepared state survives connection loss
COMMIT PREPAREDandROLLBACK PREPAREDare available from a later session
Row-Locking Clauses
Section titled “Row-Locking Clauses”The current server supports:
FOR UPDATEFOR SHARENOWAITSKIP LOCKED
FOR UPDATE
Section titled “FOR UPDATE”BEGIN;SELECT * FROM accounts WHERE id = 42 FOR UPDATE;UPDATE accounts SET balance = balance - 100 WHERE id = 42;COMMIT;FOR SHARE
Section titled “FOR SHARE”BEGIN;SELECT * FROM products WHERE id = 1 FOR SHARE;COMMIT;NOWAIT
Section titled “NOWAIT”BEGIN;SELECT * FROM accounts WHERE id = 42 FOR UPDATE NOWAIT;SKIP LOCKED
Section titled “SKIP LOCKED”BEGIN;
SELECT *FROM jobsWHERE status = 'pending'ORDER BY created_atLIMIT 1FOR UPDATE SKIP LOCKED;
COMMIT;Unsupported Lock Variants
Section titled “Unsupported Lock Variants”The PostgreSQL clauses below are not part of the current implementation:
FOR NO KEY UPDATEFOR KEY SHARE
Isolation-Level Caveat
Section titled “Isolation-Level Caveat”ParticleDB does not currently accept PostgreSQL SERIALIZABLE requests over the PG wire protocol. Clients that issue:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;or BEGIN ISOLATION LEVEL SERIALIZABLE receive an error telling them to use read committed.
Operationally, choose the engine’s behavior with --txn-mode at server start instead.
Best Practices
Section titled “Best Practices”- Keep transactions short.
- Retry write-conflict failures at the application layer.
- Use
SKIP LOCKEDfor worker-queue style consumers. SAVEPOINT,RELEASE SAVEPOINT, andROLLBACK TO SAVEPOINTare supported for partial rollback within a transaction; still prefer short transactions where practical.- Pick
--txn-modedeliberately; it changes correctness and throughput characteristics more than SQL text does.