Prisma 处理数据库竞态一般靠这几种方式:
- 事务
$transaction
csharp
await prisma.$transaction(async (tx) => {
const user = await tx.user.findUnique({ where: { id } })
await tx.user.update({
where: { id },
data: { balance: user.balance - 100 },
})
})
- 原子更新,避免先查再改
css
await prisma.user.update({
where: { id },
data: {
balance: { decrement: 100 }, // 值字段 balance 减 100
},
})
await prisma.users.update({
where: { userName },
data: {
tokenBalance: { increment: 100 }, // 使值 加
}
})
- 唯一约束 +
upsert/ 捕获冲突
css
await prisma.user.upsert({
where: { email },
create: { email },
update: {},
})
- 乐观锁 加一个
version字段:
css
await prisma.user.updateMany({
where: { id, version },
data: {
name,
version: { increment: 1 },
},
})
如果更新数量是 0,说明被别人改过。
- 设置事务隔离级别
dart
await prisma.$transaction(
async (tx) => {
// ...
},
{ isolationLevel: 'Serializable' }
)
- 悲观锁 Prisma 没有直接 API,可用原生 SQL:
sql
await tx.$queryRaw`SELECT * FROM "User" WHERE id = ${id} FOR UPDATE`
简单说:
优先用原子操作 + 唯一约束;复杂逻辑用事务;高并发冲突用乐观锁或 Serializable。