技术文章第一时间送达! 源码精品专栏 来源:http:///EhKG87r 正是因为这样,我们开发了V3版本,去解决这个问题。 V3版本,我们把订单系统的逻辑从PHP中抽离出来,为什么尽量不在PHP里面做这块逻辑呢?主要有两个考虑点:1、因为订单服务这块逻辑特别重要,是影响用户操作的重要逻辑,且变动少,写成一个SERVER相对容易保持稳定。2、PHP使用CI框架做事务的时候,如果事务中出现异常,可能导致事务不结束,一直死锁的问题。 订单系统的逻辑架构大致如下:
订单系统中,统一通过接口调用,去访问库存管理,优惠券系统,通过mysql提供的事务机制去操作数据库部分。这里有一个前提条件,即是库存管理与优惠券系统的接口均要实现可重入的特性(可参考上一篇文章“如何实现可重入接口”)。另外,还要引入一个差错控制服务,用于做一些数据不一致的事后补尝机制。差错控制可以理解为一个消息队列机制,还有一个消费者服务从队列中取出消息进行消费。我们这里采用阿里云的ONS服务做为消息队列,通过一个消费者去订单消息进行消费。 生成订单的逻辑如下: 1、先把生成的订单号发到差错控制服务中。(这里必须要有个延时处理的机制,延时给消费者消费消息,因为要确保后面的流程有个结果,可以延时5分钟以上) 2、使用订单号作为库存单号去操作库存管理系统。 A)如果失败,则使用相同订单号去进行回滚请求操作。(这里不论成功失败,均返回失败,结束流程) B)如果成功,继续往下执行。 3、使用订单号去锁定优惠券系统。 A)如果失败,尝试库存回滚操作,尝试执行解锁操作。(这里不论解锁成功失败,均返回失败,结束流程) B)如果成功,继续往下执行。 4、开启事务,创建订单相关数据。 A)如果创建失败,回滚事务,调用库存回滚操作,调用优惠券解锁操作。(不论调用成功与否,均返回失败,结束流程) B)如果创建成功,提交事务,返回成功。 大概流程如上所述。 另外,差错控制服务,这里也大概描述一下其工作流程。 1、去订单库中查看该订单是否已经生成,如果已经生成,说明数据全部一致,无须做任何操作,直接消费此消息。 2、如果发现订单未创建,则其中可能是其中某个环节失败了。 A)使用该订单号去调用库存回滚操作。如果失败,结束流程,返回稍后重新消费,等待消息队列重试推过来。 B)如果成功,继续往下执行,调用优惠券系统进行解琐优惠券。如果失败,则返回稍后重新消费,等待消息队列重推消息。如果成功,则消费此消息。 大致思路是通过一个差错补尝机制,非实时的自动进行数据一致性修复的方法,来保证绝大多数情况下的数据一致性。 |
|