Batch and transactions
Batch and transaction helpers accept DbQuery objects. A statement can come
from the Table API or raw SQL.
Use database.batch(...) when you want to send several statements together:
await database.batch([ database.table("posts").insert({ id, title, body, authorId, }), database.sql( "insert into audit_logs (id, action, targetId) values (?, ?, ?)", [auditId, "post.created", id], ),])On one-shard databases, batch execution maps naturally to the single D1 target.
Transaction
Section titled “Transaction”Use database.transaction(...) for an atomic logical write:
await database.transaction((tx) => [ tx.table("posts").update({ title, body }).where({ id }), tx.sql( "insert into audit_logs (id, action, targetId) values (?, ?, ?)", [auditId, "post.updated", id], ),])The callback receives a transaction context with tx.table(...),
tx.sql(...), and tx.statement(...).
Shard Hints
Section titled “Shard Hints”For sharded databases, pass a shard hint when the statements belong to one logical partition:
await database.transaction((tx) => [ tx.table("posts").update({ title }).where({ id }), tx.table("post_events").insert({ id: eventId, postId: id, authorId, type: "title.changed", }),], { shard: { table: "posts", key: authorId, },})The table must be listed in db({ sharding }), and key should be the value
from that table’s configured key column.
Per-Shard Groups
Section titled “Per-Shard Groups”batchPerShard(...) and transactionPerShard(...) run grouped statements with
non-atomic batch metadata. They are useful for operations that can be split by
shard:
await database.batchPerShard([ database.sql("delete from expired_sessions where expiresAt < ?", [now]),])Use transaction(...) for user-facing writes that need atomic behavior.
Empty Batches
Section titled “Empty Batches”A batch requires at least one statement. Build the statement list first when a route has optional work:
const statements = []
if (titleChanged) { statements.push(database.table("posts").update({ title }).where({ id }))}
if (statements.length > 0) { await database.batch(statements)}