uni-app 使用事务时无法用 where 进行多条件 update
uni-app 使用事务时无法用 where 进行多条件 update
操作步骤:
- 事务里面用了
where进行多条件查询
预期结果:
- 应该不会报错
实际结果:
{"code":"FUNCTIONS_EXECUTE_FAIL","message":"[FailedOperation.Abort] Abortfail. Retry your request, but if the problem persists,contact us.
Error: [FailedOperation.Abort] Abortfail. Retry your request, but if the problem persists,contact us.
at Object.exports.E (/var/user/node_modules/@cloudbase/node-sdk/lib/utils/utils.js:24:12)
at processReturn (/var/user/node_modules/@cloudbase/node-sdk/lib/utils/utils.js:43:19)
at Object.exports.default (/var/user/node_modules/@cloudbase/node-sdk/lib/utils/httpRequest.js:377:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)","requestId":"bec8e1b27b094"}
bug描述:
在高并发抢购商品时,需要用到事务,在扣减库存的环节,为了避免订单超卖,用了 where 查询,但是报错:
{
"code": "FUNCTIONS_EXECUTE_FAIL",
"message": "[FailedOperation.Abort] Abortfail. Retry your request, but if the problem persists,contact us.
Error: [FailedOperation.Abort] Abortfail. Retry your request, but if the problem persists,contact us.
at Object.exports.E (/var/user/node_modules/@cloudbase/node-sdk/lib/utils/utils.js:24:12)
at processReturn (/var/user/node_modules/@cloudbase/node-sdk/lib/utils/utils.js:43:19)
at Object.exports.default (/var/user/node_modules/@cloudbase/node-sdk/lib/utils/httpRequest.js:377:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)",
"requestId": "bec8e1b27b094"
}
以下是扣减库存的代码:
// 启动事务
const transaction = await db.startTransaction();
//减少商品库存 stock: dbCmd.gt(product.number) // TODO 限制库存大于下单库存量的才允许扣除库存
const reduceRes = await db.collection('product')
.where({
_id: product_id, // 商品ID
stock: dbCmd.gte(1) // 限制库存大于下单量的才允许扣除库存
})
.update({
stock: dbCmd.inc(-1)
})
if (reduceRes.updated === 0) {
await transaction.rollback()
return {
status: 0,
msg: '商品 1 秒前被抢完'
}
}
await transaction.commit()
更多关于uni-app 使用事务时无法用 where 进行多条件 update的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你这更新!都没放事务里吧,这事务有用?
const updateAAARes = await transaction.collection(‘account’).doc(‘aaa’).update({
amount: dbCmd.inc(-10)
})
要这样,而且对于修改和删除仅支持使用doc方法,不支持使用where方法。
可以先查找判断,再更新
更多关于uni-app 使用事务时无法用 where 进行多条件 update的实战教程也可以访问 https://www.itying.com/category-93-b0.html
根据错误信息和代码分析,这个问题是由于事务中的 where 条件查询与更新操作在云开发事务中的限制导致的。
在云开发的事务处理中,where 条件查询后直接进行 update 操作时,如果查询条件包含多个字段(特别是包含 dbCmd.gte(1) 这样的操作符条件),可能会导致事务失败并返回 FailedOperation.Abort 错误。
解决方案是使用事务的 get 方法先获取数据,然后在事务中直接使用 update 方法:
const transaction = await db.startTransaction();
const productCollection = transaction.collection('product');
// 先获取商品信息
const productDoc = await productCollection.doc(product_id).get();
const currentStock = productDoc.data[0].stock;
// 检查库存
if (currentStock < 1) {
await transaction.rollback();
return {
status: 0,
msg: '商品库存不足'
};
}
// 直接更新库存
const reduceRes = await productCollection.doc(product_id).update({
stock: dbCmd.inc(-1)
});
await transaction.commit();
或者使用事务的 update 方法配合文档引用:
const transaction = await db.startTransaction();
const productRef = transaction.collection('product').doc(product_id);
// 直接更新,通过返回值判断是否成功
const reduceRes = await productRef.update({
stock: dbCmd.inc(-1)
});
// 检查更新是否成功
if (reduceRes.updated === 0) {
await transaction.rollback();
return {
status: 0,
msg: '商品库存不足'
};
}
await transaction.commit();

