资讯专栏INFORMATION COLUMN

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

Tamic / 712人阅读

摘要:分布式事务一直是微服务的一个难点。相关的解决方案和框架大部分是的,那么该如何解决呢下面一步一步讲解如何用解决分布式事务。框架极简高性能松耦合分布式可运行于多种环境框架完美支持上面的要求。

分布式事务一直是微服务的一个难点。相关的解决方案和框架大部分是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个步骤。

开始事务

执行逻辑代码

提交事务

回滚事务

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

我们用一个常用的例子:下单。
主要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服务提供了链式调用(多个请求复用同一个对象)的功能。

可能有人要问:如果因为网络问题或者其他问题导致最后一个服务的最后一次调用失败了怎么办?
解决方案就是事务补偿,你可以把这类极端的情况下的错误,放到一个队列里 起一服务来专门处理这里问题。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/31504.html

相关文章

  • PHP 服务布式事务】阅读提示

    摘要:前几天写一篇,一种新思路实现分布式事务的文章。写个分布式事务就有人开始喷了事务提交了,怎么回滚都知道怎么回滚。 前几天写一篇 , 一种新思路实现分布式事务的文章。https://segmentfault.com/a/11... 部分死脑筋就开始,各种不解。看反馈 确实有点搞笑。 不要一听到 session 就觉得是 $_SEESION不要别人换个名字 token 或者 jwt 就不认识...

    canger 评论0 收藏0
  • SwoftRPC服务介绍

    摘要:微服务做的事情是按照项目颗粒度进行服务的拆分,把模块单独拿出来做成每一个单独的小项目。给我们提供了的底层服务,我们并不需要去关心底层通讯细节和调用的过程。通过定义接口,实现接口,启动提供接口服务。 RPC 服务 RPC,是一种远程调用方式(Remote Procedure Call),通过RPC我们可以像调用本地方法一样调用别的机器上的方法,用户将无感服务器与服务器之间的通讯。RPC在...

    娣辩孩 评论0 收藏0
  • database

    摘要:它是第一个把数据分布在全球范围内的系统,并且支持外部一致性的分布式事务。目的是使得开发者阅读之后,能对项目有一个初步了解,更好的参与进入的开发中。深度探索数据库并发控制技术并发控制技术是数据库事务处理的核心技术。 存储过程高级篇 讲解了一些存储过程的高级特性,包括 cursor、schema、控制语句、事务等。 数据库索引与事务管理 本篇文章为对数据库知识的查缺补漏,从索引,事务管理,...

    csRyan 评论0 收藏0
  • 后端好书阅读与推荐(续四)

    摘要:后端好书阅读与推荐系列文章后端好书阅读与推荐后端好书阅读与推荐续后端好书阅读与推荐续二后端好书阅读与推荐续三后端好书阅读与推荐续四这里依然记录一下每本书的亮点与自己读书心得和体会,分享并求拍砖。 后端好书阅读与推荐系列文章:后端好书阅读与推荐后端好书阅读与推荐(续)后端好书阅读与推荐(续二)后端好书阅读与推荐(续三)后端好书阅读与推荐(续四) 这里依然记录一下每本书的亮点与自己读书心得...

    phodal 评论0 收藏0

发表评论

0条评论

Tamic

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<