【发布时间】:2020-03-30 09:27:37
【问题描述】:
我有一个包含以下列的表格:id(int), wallet_id (int), amount (int), recharge_date (timestamp), status (int)。 status 表示挂起(0)、成功(1) 或失败(2)。我需要在充值之前确保当月充值的总金额不超过10,000。我还需要涵盖同时有 2 个或更多充电请求的场景。
我认为以下步骤可以帮助避免竞争条件:
- 插入状态为 0(待处理)的表中,获取 wallet_id 说“1234”
- 从其中 wallet_id = 1234 AND month(recharge_date) = 当前月份和 (0,1) 中的状态的表中选择 sum(amount)
- 如果此总和超过 10,000,则将状态更新为 2(失败)并返回。
- 执行一些应用程序级别的操作,然后将状态更新为 1(成功)或 2(失败)
这些步骤是否确保线程安全?另外,mysql中还有其他更简单的方法来确保这个用例的线程安全吗?
编辑: 解释实际流程以更清晰:
- 服务器收到请求为某个 wallet_id(比如 99)添加 500 的金额。
- 插入一个处于待处理状态的新订单:INSERT INTO orders VALUES(wallet_id = 99,amount = 500,status = pending)
- 需要保证一个月最多可以充值10000。所以 SELECT SUM(amount) WHERE wallet_id = 99 AND month=current_month AND status IN(pending, success)
- 如果步骤 3 中的总和 >= 10,000,则将步骤 2 中创建的订单状态更新为失败。返回
- 如果总和小于 10,000,则执行其他操作,返回并更新在第 2 步中创建的订单以成功或失败。
如果此流同时收到多个请求,则会出现混乱。
【问题讨论】:
标签: mysql concurrency transactions