PHP +mysql 应用怎么防止重复插入

2017-10-31 16:13:00 +08:00
 shenmeshibanjiao
1、我有一个 API,可以转账发红包之类的,余额是调用别人的 API 获取的,她的 API 没有判断是否余额充足,所以可能出现负数的情况。所以每次操作是我通过调用他的余额的 API 去判断当前操作是否是 余额充足的。
2、APP 端快速点击的时候,可能会出现负数的情况,数据库插入了很多时间戳相同的记录。
这种情况应该怎么解决呀。
3967 次点击
所在节点    PHP
20 条回复
tradzero
2017-10-31 16:53:41 +08:00
有个很丑的实现 app 端请求的时候把时间戳带上 然后后端请求完成之后把这个时间戳放到 cache 里 然后每次这个 api 请求的时候判断时间戳在不在 cache 里 如果在就直接返回失败 这样就可以避免快速点击的问题 至于防止重复插入 由于你没办法查询余额是否充足.. 理论上是没什么办法避免的吧
abcfyk
2017-10-31 16:57:51 +08:00
1. 前端应有请求队列。
2. 后端所有这种和钱有关的,全部上事务
shenmeshibanjiao
2017-10-31 17:02:10 +08:00
@abcfyk 这个订单表都是用了事务的。我大概的流程是这样的,判断交易密码、调用 API 获取余额,判断余额是否充足,之后开启事务、生成订单、然后再是转账 成功了在 commit 否则就 rollback .但是现在还是有现在的情况的,连续点击多次请求,多条订单记录,余额可能出现负数。
shenmeshibanjiao
2017-10-31 17:03:04 +08:00
@tradzero 谢谢老哥,我看我的订单表的时间戳都是一样的- -.
tabris17
2017-10-31 17:07:20 +08:00
使用 token。一动作一令牌
klgd
2017-10-31 17:08:10 +08:00
余额是在哪个环节扣的?
另外 上游 API 有问题 你作为下游应用也不可能保证没问题的
qiuyk
2017-10-31 17:09:26 +08:00
shenmeshibanjiao
2017-10-31 17:09:26 +08:00
@klgd 我大概的流程是这样的,判断交易密码、调用 API 获取余额,判断余额是否充足,之后开启事务、生成订单、然后再是转账 成功了在 commit 否则就 rollback .
silentoy
2017-10-31 17:10:20 +08:00
@shenmeshibanjiao 金额字段应该设置成无符号的,这样 update 的时候如果金额小于订单金额就会失败,从而触发 rollback
R18
2017-10-31 17:11:49 +08:00
我觉得这应该是他解决的问题不应该是你
Redis incr 不知可否解决你的问题
mahone3297
2017-10-31 17:12:23 +08:00
@abcfyk 都说了,请求队列。那就不可能出现为负数的情况。
你应该,每次处理转账的时候,都去请求判断余额。[请求判断余额,扣减]这整个是一个事务,这是一个原子。
shenmeshibanjiao
2017-10-31 17:13:42 +08:00
@silentoy 因为余额都是获取 API 的,所以我的数据库是没有存储余额的,这样的话我是否可以尝试一下增加余额,每次操作之后再去获取余额存进去 ^_^ ,谢谢老哥。
SP00F
2017-10-31 17:14:04 +08:00
开了事务的话,检查一下事务级别。把事务级别调整一下再测试。

出现负数是因为脏读了。
Sikoay
2017-10-31 17:14:37 +08:00
事务判断余额是不是就能解决余额为负
silentoy
2017-10-31 17:18:10 +08:00
@shenmeshibanjiao 如果余额是通过 API 获取的话,确实如 @klgd 所说,事务的控制应该是在上游的余额 API 端控制了,你这边很难处理
klgd
2017-10-31 17:31:43 +08:00
@shenmeshibanjiao #8 “转账”是指请求 API 去扣余额吗?
你这个逻辑设计的有问题啊,如果你这边失败了,扣余额成功了怎么办?
irory
2017-10-31 17:37:11 +08:00
来一发分布式锁 ,比如 redis lock,就能解决了呀 !
FYK
2017-10-31 17:40:28 +08:00
@abcfyk。。。好巧
shenmeshibanjiao
2017-11-01 11:42:49 +08:00
@klgd 老哥,那该怎么弄~
klgd
2017-11-01 16:47:28 +08:00
@shenmeshibanjiao #19 我不清楚你们的余额是什么概念,为什么下订单时扣除,有没有可能在订单过程中不与余额交互,然后在其他逻辑里处理余额

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/402312

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX