如何防止数据库获取以前未更新的旧数据
Posted
技术标签:
【中文标题】如何防止数据库获取以前未更新的旧数据【英文标题】:How to prevent database getting previous old unupdated data 【发布时间】:2022-01-21 21:43:55 【问题描述】:我正在尝试在 express 服务器中使用带有 graphql 的 postgresQL。 我面临的问题是当用户在客户端调用 API 时我想更新数据库的值。短时间调用两次,由于用户的钱和产品的数量还没有更新,这两个函数都会得到一些钱,执行,产品的数量和用户的钱都是负数,这是不正确的。 什么是锁功能的简单实现,使特定用户的数据行和产品的数据行在前一个过程完成之前无法访问和修改,从而实现线程安全?
编辑:我知道我可以在本地缓存中添加一个锁,但我想问一下典型的句柄方法是什么?比如我会在进程被锁定时返回正在运行的进程?或者我只是创建一个循环来等待第一个请求完成?如果有任何好的代码示例,我可以继续学习。
@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);
【问题讨论】:
选择更新并让您的应用程序在遇到锁定时失败/等待。 【参考方案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)...
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。以上是关于如何防止数据库获取以前未更新的旧数据的主要内容,如果未能解决你的问题,请参考以下文章