跳转到内容
View in the app

A better way to browse. Learn more.

彼岸论坛

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
欢迎抵达彼岸 彼岸花开 此处谁在 -彼岸论坛

[程序员] 事关破产, 求助如何写用户扣费逻辑

发表于

我在写个功能:

1.调用第三方企业收费 API 转卖给个人,用户充值获得积分之后才能使用 API,自己先垫付钱.

2.第三方 API 调用失败不扣费.

3.我搞了多个队列来限流用户的请求,大概 20 多个.

4.数据库用的 MongoDB

这是精简版数据模型

数据表

id
userId // 用户 id
status // pending progress success fail
requestData // 用户的数据
resultData // 调用第三方 api 的结果

积分表

point 

先保存用户的 requestData 请求数据, status 默认为 pending, 然后把这条数据给到 queue 队列, 队列里来处理逻辑.

下面是我的逻辑:

// 在开始事务
startTransaction();

try{

// 1.拿着 userId 查积分表 不足就 throw
if(point < 0) throw error NotEnoughPointError

// 2.如果处理成功过, 又因为某些原因又加入到 queue 里了
if(status == success) throw error AlreadyInQueueError

// 3.状态改为 progress
await setProgress()

// 4.转换一下用户格式 不修改表里的数据
await transformRequestData()

// 5.调用第三方 API 失败会抛出 ThirdAPIRrror
const result = await thirdAPI()

// 6.扣用户的积分
await minusUserPoint()

// 7.状态改为 success
await setSuccess()

// 8.提交事务
commitTransaction()

// 9.从队列里返回数据
return result

}catch(error){

// 1.终止事务
abortTransaction()

// 2.设置成错误状态
await setFail()

} finally {

// 1.结束事务
endSession();

}

问题来了...

1.我 20 多个队列同时大量这种请求, 队列是 Redis, 我加上这个事务是不是能解决并发扣费问题, 会不会多个操作同时扣费.

2.如果从 try 里面的调用第三方 API 之后的 6.扣用户的积分 7.状态改为 success 8.提交事务 这三个操作内部 throw 出错了,我钱就白花了.

3.我这逻辑有没有其他问题啊,实在没写过扣费,谢谢大家了.

Featured Replies

No posts to show

创建帐户或登录来提出意见

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.