事务和锁
注意
使用事务处理的话,需要数据库引擎支持事务处理。比如 MySQL 的 MyISAM 不支持事务处理,需要使用 InnoDB 引擎。
锁 lock()
- @param
lockStr
锁类型,默认FOR UPDATE
- 排它锁
FOR UPDATE
- 共享锁
LOCK IN SHARE MODE
- 注意:锁要在事务中使用,不可单独使用
事务 beginTransaction()
事务配合锁解决并发超卖的问题
async buy() {
try {
await Db().beginTransaction(async (TDb: any) => {
const goods = await TDb('goods').where('id', 1).lock().findOne()
if (goods.stock > 0) {
TDb('goods').where('id', 1).decr('stock')
} else {
ApiException('库存不足')
}
return ShowSuccess('购买成功')
})
} catch (e) {
ApiException('异常')
}
}
async buy() {
try {
await Db().beginTransaction(async (TDb: any) => {
const goods = await TDb('goods').where('id', 1).lock().findOne()
if (goods.stock > 0) {
TDb('goods').where('id', 1).decr('stock')
} else {
ApiException('库存不足')
}
return ShowSuccess('购买成功')
})
} catch (e) {
ApiException('异常')
}
}
最终的SQL语句为:
START TRANSACTION
SELECT * FROM goods WHERE id = 1 FOR UPDATE
UPDATE goods SET stock = stock - 1 WHERE id = 1
COMMIT
START TRANSACTION
SELECT * FROM goods WHERE id = 1 FOR UPDATE
UPDATE goods SET stock = stock - 1 WHERE id = 1
COMMIT