Transactions
Standalone operations each run in their own transaction. To write to several collections together, all or nothing, use db.transaction():
ts
const userId = await db.transaction(['users', 'notes'], 'readwrite', async (tx) => {
const id = await tx.users.insert({ name: 'Sara', email: 'sara@example.com', age: 25, tags: [] })
await tx.notes.insert({ slug: `welcome-${id}`, userId: id, body: 'Hello!' })
return id
})db.transaction() resolves with the callback's return value, after the transaction commits.
Rules
- Everything commits together, or nothing does. If the callback throws, or any request fails (even one you catch), the whole transaction is rolled back.
- Only await operations on
txinside the callback. IndexedDB commits a transaction as soon as it has no pending requests, so awaitingfetch(), timers or other I/O ends it early. doxor detects this and rejects with the codeTransactionInactive. Do that work before or after the transaction. - Use
tx, notdb.db.usersinside the callback runs outside the transaction. - A
readonlytransaction rejects writes with the codeReadOnly.
Every doxor operation is available on tx.<collection>, including queries.