支付系统中要避免支付状态并发BUG
支付系统表设计
有一个支付订单表( TB_ORDER ):(主要字段)
字段名 | 字段类型 | 描述 |
OrderID | varchar(50) | 订单号 |
UserID | varchar(50) | 充值用户 |
Amount | decimal(18,2) | 充值金额 |
PayType | varchar(50) | 支付类型:微信\支付宝 |
CreateTime | datetime | 订单生成时间 |
Status | int | 状态:0 未支付 1已支付 |
PayDateTime | datetime | 支付时间 |
支付流程
- 系统生成
微信支付
/支付宝支付
付款二维码 - 用户打开
支付宝
/微信
扫描二维码付款 - 界面会轮询调用后台接口,查询订单状态是否已经完成,如果完成,在用户表中的
用户余额
加上充值金额
- 如果用户付款完成后,界面没有获取到付款状态,则用户可以点击页面上的
我已付款
按钮来手动的查询订单状态
正常情况下,这个流程是没问题的,当 查询订单 返回用户付款状态是已付款的时候,就把 tb_order 表的状态改为 已支付,同时用户表余额增加,当再次调用这个接口的时候,发现数据库中 tb_order 表中的状态已经是已付款,就不在处理了
BUG
但是这里有个问题,查询订单支付状态
是一个耗时的操作,如果我利用工具,在同一个时间调用尽可能多(成百上千次)的 订单查询接口,这样,可能出现 并发
,同时有 >1 个进程通过了 tb_order 表的状态判断( 并发过程中,状态都是未支付 ),然后去微信或支付宝中调用订单状态查询,查询到已支付,然后修改 tb_order 表状态,并且给用户增加金额,这里的 增加金额
动作,就有可能 重复增加
了。
解决方案
tb_order 表中增加一个RowVersion
字段,字段类型为 timestamp ,利用 RowVersion 字段来防止 tb_order 表状态字段 status 的并发修改,
每次修改 tb_order 数据的时候,对应数据的 RowVersion
列就会递增,增加了 RowVersion 列后,每次修改数据,校验一下 RowVersion 是否一致,如果不一致就抛出异常,不会再向下执行
详细信息参考:
EF并发处理,防止并发修改数据 - 文章随笔 - YES快速开发平台框架,C#快速开发平台框架,WEB快速开发框架,.NET开发框架,.NET WEB开发平台框架 (yesdotnet.com)
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post YES开发框架