skills/prisma-client-api-transactions/SKILL.md
Transactions. Reference when using this Prisma feature.
npx skillsauth add prisma/cursor-plugin prisma-client-api-transactionsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Execute multiple operations atomically.
Array of operations executed in order:
const [user, post] = await prisma.$transaction([
prisma.user.create({ data: { email: '[email protected]' } }),
prisma.post.create({ data: { title: 'Hello', authorId: 1 } })
])
If any operation fails, all are rolled back:
try {
await prisma.$transaction([
prisma.user.create({ data: { email: '[email protected]' } }),
prisma.user.create({ data: { email: '[email protected]' } }) // Duplicate!
])
} catch (e) {
// Both operations rolled back
}
For complex logic and dependent operations:
await prisma.$transaction(async (tx) => {
// Decrement sender balance
const sender = await tx.account.update({
where: { id: senderId },
data: { balance: { decrement: amount } }
})
// Check balance
if (sender.balance < 0) {
throw new Error('Insufficient funds')
}
// Increment recipient balance
await tx.account.update({
where: { id: recipientId },
data: { balance: { increment: amount } }
})
})
await prisma.$transaction(
async (tx) => {
// operations
},
{
maxWait: 5000, // Max wait to acquire lock (ms)
timeout: 10000, // Max transaction duration (ms)
isolationLevel: 'Serializable' // Isolation level
}
)
| Level | Description |
|-------|-------------|
| ReadUncommitted | Lowest isolation, can read uncommitted changes |
| ReadCommitted | Only read committed changes |
| RepeatableRead | Consistent reads within transaction |
| Serializable | Highest isolation, serialized execution |
Automatic transactions for nested operations:
// This is automatically a transaction
const user = await prisma.user.create({
data: {
email: '[email protected]',
posts: {
create: [
{ title: 'Post 1' },
{ title: 'Post 2' }
]
},
profile: {
create: { bio: 'Hello!' }
}
}
})
The tx parameter is a Prisma Client scoped to the transaction:
await prisma.$transaction(async (tx) => {
// Use tx instead of prisma
await tx.user.create({ ... })
await tx.post.create({ ... })
// Can call methods
const count = await tx.user.count()
})
Use with interactive transactions:
await prisma.$transaction(async (tx) => {
// If not found, throws and rolls back entire transaction
const user = await tx.user.findUniqueOrThrow({
where: { id: 1 }
})
await tx.post.create({
data: { title: 'New Post', authorId: user.id }
})
})
// Good - only DB operations in transaction
const data = prepareData() // Outside transaction
await prisma.$transaction(async (tx) => {
await tx.user.create({ data })
})
try {
await prisma.$transaction(async (tx) => {
// operations
})
} catch (e) {
if (e.code === 'P2002') {
// Handle unique constraint violation
}
throw e
}
// Default is fine for most cases
await prisma.$transaction(async (tx) => {
// operations
})
// Use Serializable for strict consistency
await prisma.$transaction(
async (tx) => { /* operations */ },
{ isolationLevel: 'Serializable' }
)
| Feature | Sequential | Interactive | |---------|------------|-------------| | Syntax | Array | Async function | | Dependent ops | No | Yes | | Conditional logic | No | Yes | | Performance | Better | More flexible | | Use case | Simple batch | Complex logic |
databases
Schema Changes. Reference when using this Prisma feature.
tools
Removed Features. Reference when using this Prisma feature.
tools
Prisma Config. Reference when using this Prisma feature.
tools
ESM Support. Reference when using this Prisma feature.