Transactions
file-json-db supports snapshot transactions.
All changes made inside a transaction stay in memory until you call
commit(). If you call rollback() the original
files on disk are left completely untouched.
How it works
- You call
collection.startTransaction(). - The library deep-clones the current in-memory index and creates an overlay for part data.
- Every insert / update / delete that goes through the transaction object mutates only the overlay.
commit()writes the overlay to disk and updates the real index.rollback()discards the overlay; disk stays as it was.
One transaction at a time
Only one transaction may be active on a given collection.
Starting a second one while the first is still open throws an error.
Basic example
const tx = users.startTransaction();
try {
tx.insert({ name: 'Alice', email: 'alice@example.com' });
tx.insert({ name: 'Bob', email: 'bob@example.com' });
tx.updateOne(
{ name: 'Alice' },
{ $set: { role: 'admin' } }
);
// Nothing has been written to disk yet
await tx.commit(); // now the changes become permanent
} catch (err) {
await tx.rollback(); // discard everything
throw err;
}
Transaction API
The transaction object exposes the same mutation methods as a collection:
insert/insertAsyncinsertMany/insertManyAsyncupdateOne/updateOneAsyncupdateMany/updateManyAsyncdeleteOne/deleteOneAsyncdeleteMany/deleteManyAsyncupdateFunc/updateFuncAsynccommit()→ Promise<boolean>rollback()→ Promise<boolean>
When to use transactions
- You need several related writes to succeed or fail together.
- You want to be able to abort a multi-step operation cleanly.
- You are implementing business logic that must stay consistent (e.g. transfer points from one user to another).
Limitations
- Transactions are per-collection, not multi-collection.
- Only one active transaction per collection.
- Reads performed outside the transaction still see the old data until commit.
- Very large transactions (hundreds of thousands of documents) will consume significant memory because the overlay lives in RAM.