
1 tradzero 2017-10-31 16:53:41 +08:00 有个很丑的实现 app 端请求的时候把时间戳带上 然后后端请求完成之后把这个时间戳放到 cache 里 然后每次这个 api 请求的时候判断时间戳在不在 cache 里 如果在就直接返回失败 这样就可以避免快速点击的问题 至于防止重复插入 由于你没办法查询余额是否充足.. 理论上是没什么办法避免的吧 |
2 abcfyk 2017-10-31 16:57:51 +08:00 1. 前端应有请求队列。 2. 后端所有这种和钱有关的,全部上事务 |
3 shenmeshibanjiao OP @abcfyk 这个订单表都是用了事务的。我大概的流程是这样的,判断交易密码、调用 API 获取余额,判断余额是否充足,之后开启事务、生成订单、然后再是转账 成功了在 commit 否则就 rollback .但是现在还是有现在的情况的,连续点击多次请求,多条订单记录,余额可能出现负数。 |
4 shenmeshibanjiao OP @tradzero 谢谢老哥,我看我的订单表的时间戳都是一样的- -. |
5 tabris17 2017-10-31 17:07:20 +08:00 使用 token。一动作一令牌 |
6 klgd 2017-10-31 17:08:10 +08:00 余额是在哪个环节扣的? 另外 上游 API 有问题 你作为下游应用也不可能保证没问题的 |
7 qiuyk 2017-10-31 17:09:26 +08:00 她 |
8 shenmeshibanjiao OP @klgd 我大概的流程是这样的,判断交易密码、调用 API 获取余额,判断余额是否充足,之后开启事务、生成订单、然后再是转账 成功了在 commit 否则就 rollback . |
9 silentoy 2017-10-31 17:10:20 +08:00 @shenmeshibanjiao 金额字段应该设置成无符号的,这样 update 的时候如果金额小于订单金额就会失败,从而触发 rollback |
10 R18 2017-10-31 17:11:49 +08:00 我觉得这应该是他解决的问题不应该是你 Redis incr 不知可否解决你的问题 |
11 mahone3297 2017-10-31 17:12:23 +08:00 @abcfyk 都说了,请求队列。那就不可能出现为负数的情况。 你应该,每次处理转账的时候,都去请求判断余额。[请求判断余额,扣减]这整个是一个事务,这是一个原子。 |
12 shenmeshibanjiao OP @silentoy 因为余额都是获取 API 的,所以我的数据库是没有存储余额的,这样的话我是否可以尝试一下增加余额,每次操作之后再去获取余额存进去 ^_^ ,谢谢老哥。 |
13 SP00F 2017-10-31 17:14:04 +08:00 开了事务的话,检查一下事务级别。把事务级别调整一下再测试。 出现负数是因为脏读了。 |
14 Sikoay 2017-10-31 17:14:37 +08:00 via Android 事务判断余额是不是就能解决余额为负 |
15 silentoy 2017-10-31 17:18:10 +08:00 @shenmeshibanjiao 如果余额是通过 API 获取的话,确实如 @klgd 所说,事务的控制应该是在上游的余额 API 端控制了,你这边很难处理 |
16 klgd 2017-10-31 17:31:43 +08:00 @shenmeshibanjiao #8 “转账”是指请求 API 去扣余额吗? 你这个逻辑设计的有问题啊,如果你这边失败了,扣余额成功了怎么办? |
17 irory 2017-10-31 17:37:11 +08:00 来一发分布式锁 ,比如 redis lock,就能解决了呀 ! |
19 shenmeshibanjiao OP @klgd 老哥,那该怎么弄~ |
20 klgd 2017-11-01 16:47:28 +08:00 @shenmeshibanjiao #19 我不清楚你们的余额是什么概念,为什么下订单时扣除,有没有可能在订单过程中不与余额交互,然后在其他逻辑里处理余额 |