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

Wesley13
• 阅读 800

分布式事务一直是微服务的一个难点。相关的解决方案和框架大部分是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服务提供了链式调用(多个请求复用同一个对象)的功能。

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
一种基于柔性事务的分布式事务解决方案设计探究
1背景市面上常见的有,2pc/3pc、tcc、saga等常见的分布式事务解决方案,但是实际实施起来框架比较重,设计开发比较繁琐,不易于快速开发上手。本文提供一种基于柔性事务设计的简单易上手的分布式事务设计方案,用于解决常见的分布式事务常见
Easter79 Easter79
2年前
TiDB 性能竞赛 11.16
TiDB实现了快照隔离级别的分布式事务,支持悲观锁、乐观锁,同时也解决了大事务的难点。事务是数据库的基础,提供高效的、支持完整ACID的分布式事务更是分布式数据库的立足之本。事务是数据库执行的最小单元,允许用户将多个读写操作组合为一个逻辑单元。事务需要满足原子性、一致性、隔离性和持久性,也就是ACID。数据库有多种并发控制方法,乐观并发控制(
Wesley13 Wesley13
2年前
25 张图让你彻底掌握分布式事务原理
!(https://oscimg.oschina.net/oscnet/6455854ea467492db3d90486953b81e1.jpg)本文提纲如下0\.前言1\.单数据源事务&多数据源事务2\.常见分布式事务解决方案2.1.分布式事务模型
Stella981 Stella981
2年前
25 张图,1.4 w字!彻底搞懂分布式事务原理
!(https://oscimg.oschina.net/oscnet/0c08fb0b18a1456caf7fee690e02de5e.jpg)本文提纲如下:0\.前言1\.单数据源事务&多数据源事务2\.常见分布式事务解决方案2.1.分布式事务模型
Wesley13 Wesley13
2年前
MySQL查询缓存
1、mysql分布式事务在mysql中,使用分布式事务的应用程序涉及一个或多个资源管理器和一个事务管理器,分布式事务的事务参与者、资源管理器、事务管理器等位于不同的节点上。这些不同的节点相互协作共同完成一个具有逻辑完整性的事务。分布式事务主要作用在与确保事务的一致性和完整性。1.1、了解分布式事务的原理  资源管理器(RM):用于向事务提供资
京东云开发者 京东云开发者
5个月前
线上SQL超时场景分析-MySQL超时之间隙锁 | 京东物流技术团队
前言之前遇到过一个由MySQL间隙锁引发线上sql执行超时的场景,记录一下。背景说明分布式事务消息表:业务上使用消息表的方式,依赖本地事务,实现了一套分布式事务方案消息表名:mqmessages数据量:3000多万索引:createtime和statuss
韦康 韦康
3星期前
一课学透 分布式事务框架 Alibaba Seata
一课学透分布式事务框架AlibabaSeatadownload》itzcw.com/9340/AlibabaSeata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata将为用户提供了AT、TCC、SAGA和XA事务模式,
光之守卫 光之守卫
2星期前
一课学透 分布式事务框架 Alibaba Seata
一课学透分布式事务框架AlibabaSeatadownload》itzcw.com/9340/分布式事务框架AlibabaSeata的详细介绍文章Alibaba的Seata是一款开源的分布式事务解决方案,旨在解决微服务架构下的分布式事务问题。Seata支持
彭玘 彭玘
4天前
一课学透 分布式事务框架 Alibaba Seata
一课学透分布式事务框架AlibabaSeatadownload》chaoxingit.com/5008/分布式事务框架AlibabaSeata的介绍AlibabaSeata是一个开源的分布式事务解决方案,旨在解决分布式系统中的数据一致性问题。它提供了高效的