第三方支付同步和异步回调并发数据一致性的问题
在第三方交易系统中的支付场景下,一般的步骤是,用户在系统产生订单,支付系统向第三方发起支付请求创建支付订单,用户跳转至第三方系统进行支付,支付完成后会产生 同步回调
和 异步回调
。系统一般根据 第三方异步回调
来确认本次交易结果
特殊业务场景
由于目前存在特殊的业务场景,本次交易结果必须依赖前端的 同步回调
请求来决定用户是否能进入下一步的产品交付场景。简单来说,在特殊的业务场景下,必须依赖 同步回调
的结果来判定本次交易状态
并发一致性问题
当同步回调和异步回调同时发生的时候,由于实现细节的不同,两个流程需要将订单状态分别流转到不同的状态,由于查询数据库使用的是快照读,在某一个流程中修改状态的事务未提交的时候,查询到这条记录一样的事务提交之前的状态,所以会存在数据没有被流转到正确的处理状态
原因
在 A B 事务并发的情况下,A B 两个事务都依赖同一行数据中数据字段的状态进行下一步的操作,当 A 事务决定将状态更新到 x 时的事务还未提交的时候,B 查询到的数据状态和 A 事务是相同的,导致 B 事务会将数据字段更新到 y 导致数据结果和预期不一致
解决方式
- 事务 + 当前读
保证两个业务的查询,更新都在一个事务中,且使用当前读查询数据的最新状态 - 利用分布式锁串行化接口
由于业务强依赖同步回调,所以将同步回调与异步回调串行,使同步回调保持在异步回调之前,异步回调在同步回调请求未产生之前不进行处理
第三方异步回调返回问题
由于第三方依赖异步回调的结果来分析我方业务是否正常,如果在异步场景下直接返回异常那么在第三方的业务系统中会存在大量错误,这是我们不希望看到的。
由于不强依赖第三方的异步回调,系统可以使用消息中间件将回调消息收取,返回第三方正常,利用消息 + Job 脚本的方式对数据没有正常流转的订单进行补偿重试