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 我不清楚你们的余额是什么概念,为什么下订单时扣除,有没有可能在订单过程中不与余额交互,然后在其他逻辑里处理余额
|