如何防止数据库获取以前的旧未更新数据
How to prevent database getting previous old unupdated data
我正在尝试在 express 服务器中使用带有 graphql 的 postgresQL。
我面临的问题是我想在用户调用客户端中的 API 时更新数据库的值。短时间内调用两次时,由于用户的钱和产品的数量还没有更新,所以两个函数都会得到一些钱,执行,产品的数量和用户的钱都是负数,这是不正确的。
锁定功能的简单实现是什么,以便特定用户的数据行和产品的数据行在前一个过程完成之前无法访问和修改,从而实现线程安全?
编辑:我知道我可以在本地缓存中加一个锁,但我想问一下典型的句柄方法是什么?比如我将刚刚return进程锁定时是运行?或者我只是创建一个循环来等待第一个请求完成?如果有任何好的代码示例我可以继续。
@Mutation(() => Boolean)
async pay(@Arg('amount') amount: number) {
let userId = 1
let proeductId = 1
const user = await User.findOne(userId); // user = {userId: 1, money: 50}
const product = await Product.findOne(userId); // product= {userId:1, quantity: 1, price: 50}
await new Promise(resolve => setTimeout(resolve, 3000)) // some logic
if(user && product && user?.money >= product.price && product.quantity > 0 ){
await getConnection().getRepository(User).decrement({ userId }, 'money', 50);
await getConnection().getRepository(product).decrement({ userId }, 'quantity', 1);
}
}
}
使用 .setLock("pessimistic_write") 将解决问题
const user= await getRepository(User)
.createQueryBuilder()
.useTransaction(true)
.setLock("pessimistic_write")
.where({id:userId})
.getOne();
const product = ...
if(user && product && user?.money >= product.price && product.quantity > 0 ){
await getRepository(User)
.createQueryBuilder()
.useTransaction(true)
.update(User)
.set({money: user.money- amount})
.where({id:userId})
.execute();
await getRepository(product)...
}
我正在尝试在 express 服务器中使用带有 graphql 的 postgresQL。
我面临的问题是我想在用户调用客户端中的 API 时更新数据库的值。短时间内调用两次时,由于用户的钱和产品的数量还没有更新,所以两个函数都会得到一些钱,执行,产品的数量和用户的钱都是负数,这是不正确的。
锁定功能的简单实现是什么,以便特定用户的数据行和产品的数据行在前一个过程完成之前无法访问和修改,从而实现线程安全?
编辑:我知道我可以在本地缓存中加一个锁,但我想问一下典型的句柄方法是什么?比如我将刚刚return进程锁定时是运行?或者我只是创建一个循环来等待第一个请求完成?如果有任何好的代码示例我可以继续。
@Mutation(() => Boolean)
async pay(@Arg('amount') amount: number) {
let userId = 1
let proeductId = 1
const user = await User.findOne(userId); // user = {userId: 1, money: 50}
const product = await Product.findOne(userId); // product= {userId:1, quantity: 1, price: 50}
await new Promise(resolve => setTimeout(resolve, 3000)) // some logic
if(user && product && user?.money >= product.price && product.quantity > 0 ){
await getConnection().getRepository(User).decrement({ userId }, 'money', 50);
await getConnection().getRepository(product).decrement({ userId }, 'quantity', 1);
}
}
}
使用 .setLock("pessimistic_write") 将解决问题
const user= await getRepository(User)
.createQueryBuilder()
.useTransaction(true)
.setLock("pessimistic_write")
.where({id:userId})
.getOne();
const product = ...
if(user && product && user?.money >= product.price && product.quantity > 0 ){
await getRepository(User)
.createQueryBuilder()
.useTransaction(true)
.update(User)
.set({money: user.money- amount})
.where({id:userId})
.execute();
await getRepository(product)...
}