如何与第三方接口保持数据一致性

Posted Fly , Mason ! ! !

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何与第三方接口保持数据一致性相关的知识,希望对你有一定的参考价值。

大家经常遇到这样的需求,尤其是支付中心接口的时候:

查询满足某种条件的订单,调用第三方接口成功,更改订单状态。

常见实现示例

task1:

orders = queyrOrder(...); //查询已离店的订单
        for (Map<String, Object> order : orders) {
            try {
                con.setAutoCommit(false);
 
                String orderNo = (String) order.get("order_no");
 
                // 调用支付中心返现接口
                callCommission(order);  //无论是网络异常还是返回结果失败,都抛异常
                // 更改订单状态
                cashedOrder(con, order); //更改订单状态
 
                con.commit();
        }

  

task 2 

orders = queyrOrder(...);//查询“返现中”的订单
 
 for (Map<String, Object> order : orders) {
 
        con.setAutoCommit(false);
        // 调用返现任务
        callCommission(order);
 
        // 更改订单状态
        cashedOrder(con, order);
 
        con.commit();           
 
 }

  

示例的问题
  1. 在事务中存在远程调用,容易导致事务时间过长
  2. 在callCommission 和 cashedOrder之间,是否有其他操作能改变该订单状态? 如果有,是否会出现多次调用第三方的问题?
  3. 第三方接口特性未知
设计方案

往两个方面思考

  1. 自己系统本身数据一致性
  2. 如果调用第三方接口 和 更新自己系统数据 之间任何一个环节 出异常了。比如:应用重启,机房网络问题等。如何保证第三方接口和自己系统的数据一致性?

方案

  1. 加锁,方案有:版本号乐观锁、select for update 悲观锁。
    延伸问题:在原表上执行task,还是队列表?
  2. 第三方接口需要什么特性才能保证数据一致性? 要考虑网络超时问题、应用发布重启、并发等问题。
  • 回调
  • 提供结果查询
  • 幂等性
重构后的示例1:

(幂等接口的方案)


queueOrders = queryQueueOrders();
for(QueueOrder order : queueOrders){
   callApi()
   startTransaction();
   lock(order);  
   updateStatus()
   commitTransaction();
}

(提供结果查询的API接口的方案)


queueOrders = queryQueueOrders();
for(QueueOrder order : queueOrders){
   try{
      startTransaction();
      if(isBeingProcess(order)){
          Result r = queryAPIResult();
          if(r.success()){
            return;
          }
      }
      lock(order);
      callApi()
      updateStatus();
   }finally{
   commitTransaction();
   }
}

注意:该示例依然有“在事务中调用远程接口的问题”

 

http://www.cnblogs.com/NanguoCoffee/archive/2013/03/30/2990918.html

以上是关于如何与第三方接口保持数据一致性的主要内容,如果未能解决你的问题,请参考以下文章

RobotFramework之接口自动化流程测试

如何更新导航抽屉中的有状态小部件,同时在 Android 中保持与片段相同的类?

Redis 如何与数据库事务保持一致

GraphQL:Apollo 客户端缓存如何工作以保持与服务器的数据一致性?

面试官问:Redis的操作如何与数据库事务保持一致

终于懂了:Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了,跟Windows消息虽然尽量保持一致,但其实相互没有特别大的关系。有了这个,就有了主动,带不带句柄完全看需要。(代码片段