Mutations and transactions
create, createIfNotExists, createOrReplace, patch and delete — applied as one Postgres transaction, with optimistic concurrency and constraint enforcement.
Every mutation request is one Postgres transaction. Either all of it applies or none of it does.
await client
.transaction()
.createIfNotExists({ _id: 'author-jane', _type: 'author', name: 'Jane' })
.create({
_id: 'post-new',
_type: 'post',
title: 'A new post',
author: { _type: 'reference', _ref: 'author-jane' },
})
.commit()That works on an empty database because the constraint check counts the transaction's own effects as state: the reference resolves against the author the same transaction is creating.
The operations
| Operation | Behaviour |
|---|---|
create | Fails if the id exists. |
createIfNotExists | Returns the existing document untouched. |
createOrReplace | Writes unconditionally. |
patch | Applies set, setIfMissing, unset, inc, dec, insert and diffMatchPatch. |
delete | By id, or by query. |
Patching arrays
Array members are addressed by _key, not by index, which is what makes concurrent editing of a long array safe:
await client
.patch('home')
.set({ 'sections[_key=="hero"].heading': 'A new heading' })
.commit()diffMatchPatch
The Studio sends text edits as diff-match-patch payloads rather than whole values, so two people editing different paragraphs of one field do not clobber each other.
Optimistic concurrency
await client.patch('post-1', { ifRevisionID: knownRev }).set({ title: 'Renamed' }).commit()A revision mismatch is reported as a conflict. Without one, last write wins — which is occasionally what you want and usually not.
