代码逻辑不知道怎么设计

最近在开发中碰到一个问题,不知道要怎么设计逻辑比较好。希望有大佬可以帮忙提个建议。
就是在一个接口里面,我需要 请求多个第三方接口,同时根据第三方接口更新数据库。
(1)如果把第三方接口放到数据库事务里面,会导致事务执行时间太长,性能会有问题。
(2)如果把第三方接口请求放到事务外面,又没法跟数据库事务保持一致。并且如果第三方接口执行了,但是数据库事务挂了,也是麻烦。

伪代码如下:

$api = new zfb();
$db = new db();
$db->begin();
try {
    $res1 = $api->query(xxx);
    $db->update($res1);

    $res2 = $api->query2(xxx);
    $db->update($res2);

    $db->commit();
} catch (\Exception) {
    $db->rollback();
}
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 23

:joy:请求完再一起放到一个事务里更新,或者单个请求完执行单个事务

2年前 评论
Caral (楼主) 2年前
Caral (楼主) 2年前
zhangwuphp (作者) 2年前

第三方接口只是读取吗,请求了有什么影响

2年前 评论
php_yt (作者) 2年前
Caral (楼主) 2年前

请求放到事务外面,每个请求可以赋给一个变量,如果都成功就在统一事务内更新

2年前 评论
巴啦啦臭魔仙 (作者) 2年前
Caral (楼主) 2年前

用第二种方式。将数据获取和入库分开。
把调用接口操作封装成一个方法,判断所有接口成功后返回最终所有接口数据,任何一个接口请求超时或失败,retry重新调用全部接口或者单个接口(更好)。可以使用辅助函数retry方法辅助函数《Laravel 8 中文文档》 或者使用队列处理可以,队列有失败重试机制。

数据库事务不会挂,除非mysql挂了。会出现死锁
DB::transaction 方法第二个参数可以处理死锁重试机制 快速入门《Laravel 8 中文文档》

2年前 评论

如果第三方接口只是读查询,那就放到事务前全部请求; 如果第三方接口有写或依赖你的事务逻辑,简单的就是分步骤,根据你的业务情况,会有不同的复杂度,可以给主数据加个状态,支持继续下一步的操作,等等

2年前 评论
  1. 三方接口交互,保存结果
  2. 分发一个job到队列中处理步骤 1 中的结果
2年前 评论

看了你的贴子,你担心的问题无非两点。

  1. 事务崩了,三方请求正常
  2. 请求异常,事务正常

反正我的思路还是异步分发,三个请求接口可耗不起,事务先提交,队列执行三次请求。

有异常记录日志,做好异常处理就行了,没必要过于担心这些。

2年前 评论
她来听我的演唱会 2年前
MArtian (作者) 2年前
她来听我的演唱会 2年前
自由与温暖是遥不可及的梦想

第一点 弄清楚自己的需求

如果都是自己系统的很好处理

如果涉及第三方,第三方的是查询,还是操作,是否 可以进行挽回

第三方会不会执行失败

失败了怎么处理

还有就是 自己的 这个是否需要做同步处理 (是否可以用异步来出来, 异步不用担心响应速度)

拆分业务

2年前 评论
秦晓武
  1. 第三方接口之间没有依赖关系
  2. 只考虑代码逻辑

解决方案:单接口事务就行了,没必要多个第三方接口打包事务。中间有失败的,也就是多个中间状态而已,后续根据状态再继续进行。抽象起来,就是个业务审批流,只不过没有人工去一步步操作而已。

2年前 评论

上面大家已经说的比较详细了,你所关心的不同步问题,要根据具体业务来处理。

你请求的第三方接口是否有回滚操作,如果类似支付这种,无法回滚。那本地数据库更新失败,做好相关异常处理逻辑。 例如标记订单为异常订单,定时重试或者人工处理,主要是要保证所有数据都可溯,正常业务事务也不应该经常崩。

2年前 评论
Junwind

你这里可能没搞清楚,事务回滚跟你请求第三方接口没关系,事务失败了,只要你请求了第三方,还是请求了,并不会时光倒流, 这里可以异步或者同步,保证每一步都成功即可,不成功的做好错误处理机制即可

2年前 评论

三方接口也该有回滚操作的。所以只对数据库做事务,事务失败使用三方接口回滚数据

2年前 评论

可以参考下这个:
事务遇到第三方API请求如何处理 www.jianshu.com/p/afbf957501ce
如何优雅地重试 www.infoq.cn/article/5fboevkal0gvg...

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!