php微服务之【分布式事物】

栏目: PHP · 发布时间: 4年前

内容简介:分布式事物一直是微服务的一个难点。相关的解决方案和框架大部分是java的,那么php该如何解决呢?下面一步一步讲解如何用php解决分布式事物。首先从单机事物开始。大概逻辑如下 :

分布式事物一直是微服务的一个难点。相关的解决方案和框架大部分是 java 的,那么 php 该如何解决呢?下面一步一步讲解如何用php解决分布式事物。

单机单数据源事物

首先从单机事物开始。

大概逻辑如下 :

try {  
  // 开始事物
  $db->beginTransaction();
  
  // 执行你的操作 
  // ...
  
  // 提交事物
  $db->commit();
 
} catch (Exception $e) {

  // 执行失败 回滚
  $db->rollBack();
  
}

单机多个数据源事物

如果你业务涉及到多个数据库,事物大概逻辑是这个样子:

try {  
  // 开始事物
  $db1->beginTransaction();
  $db2->beginTransaction();
  
  // 执行你的操作 
  // ...
  
  // 提交事物
  $db1->commit();
  $db2->commit();
 
} catch (Exception $e) {

  // 执行失败 回滚
  $db1->rollBack();
  $db2->rollBack();
  
}

多机多数据源事物(分布式事物)

如果你的数据源和业务代码都是分开的(微服务)这就是我们今天的核心。

由前面两种情况来看,大概逻辑是差不多的,主要也分为4个步骤。

  1. 开始事物
  2. 执行逻辑代码
  3. 提交事物
  4. 回滚事物

有些文章也称为 tcc 也就是 234 步骤。

我们用一个常用的例子:下单。

主要3个步骤:

  1. 创建订单
  2. 修改库存
  3. 修改用户积分

假设订单,库存,用户都是独立的服务。

按照前面的经验大概分为4个步骤,我们以用户为例 代码如下:

class User
{
    // 开始事物
    public function beginTransaction()
    {
        $db->beginTransaction();
        return $this;
    }
    
    // 执行代码
    public function doTransaction()
    {
        // 执行你的操作 
          // ...
          return $this;
    }
    
    public function commit()
    {
        $db->commit();
    }
    
    public funtion rollBack()
    {
        $db->rollBack();
    }

}

库存(stock),订单(order)和上面类似,也需要这4个方法,我就不写了。

难点在于我们没法直接操作数据源,只能通过rpc调用相应的服务来操作。依次执行上面的方法就好了。代码如下:

try {  
  // 开始事物
  $user = new User();
  $stock = new Stock();
  $order = new Order();
  
  $user = $user->beginTransaction();
  $stock = $stock->beginTransaction();
  $order = $order->beginTransaction();
  
  
  // 执行你的操作 
  $user = $user->doTransaction();
  $stock = $stock->doTransaction();
  $order = $order->doTransaction();
  
  // 提交事物
  $user->commit();
  $stock->commit();
  $order->commit();
 
} catch (Exception $e) {

  // 执行失败 回滚
  $user->rollBack();
  $stock->rollBack();
  $order->rollBack();
  
}

到这里可能有人看出问题来了,正常情况下这样肯定是不行的。要上面这段代码成立需要满足1个条件: User 分别调用了3次,也就是3个请求。要保证这3个请求是调用的同一个实例化后的对象。 StockOrder 一样。

User 调用逻辑如下:

// 第一次请求调用
$user = new User();
$user = $user->beginTransaction();

// 第二次请求调用 复用的第一次 $user
$user = $user->doTransaction();

// 第三次请求调用 复用的第一次 $user
$user->commit();
//或者 
$user->rollBack();

注意:虽然调用了3次但是只 new 了一次, 第二次和第三次请求是复用的第一次的对象。要满足这个条件 服务供方必须 常驻内存 ,而且提供的 rpc服务 必须支持 链式调用 的功能。

one 框架 https://github.com/lizhichao/one

极简 . 高性能 . 松耦合 . 分布式 . 可运行于多种环境

one 框架完美支持上面的要求。只需要把上面的 UserStockOrder 添加为rpc服务即可。还需要注意 beginTransactiondoTransaction 方法必须返回 $this 提供给后面的方法调用。

user服务如下:

RpcServer::add(User::class);

其他两个类似。到此分布式事物问题就搞定了,可能觉得这么简单吗?这主要由于 one框架 的rpc服务提供了链式调用(多个请求复用同一个对象)的功能。

可能有人要问:如果因为网络问题或者其他问题导致最后一个服务的最后一次调用失败了怎么办?

解决方案就是 事物补偿 ,你可以把这类极端的情况下的错误,放到一个队列里 起一服务来专门处理这里问题。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据结构与算法

数据结构与算法

卓滋德克 / 陈曙晖 / 清华大学出版社 / 2003-4-1 / 69.00

本书是一本介绍数据结构与算法的优秀书籍。 本书系统介绍了C++面向对象程序设计、算法复杂度、链表、栈、队列、递归、树、图、排序和查找算法、散列技术、数据压缩算法、内存管理等内容;尤其对递归算法进行了深入剖析。在附录中详细介绍了大O符号与标准模板库:在大多数章中提供了相应的实例分析和程序设计作业。 本书适合作为计算机软件专业或其他相关专业的教科书。对于需要参加计算机考试,......一起来看看 《数据结构与算法》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具