Polardb 特殊场景下抛出There is no active transaction 求解

起因:线上的异常报警系统偶尔会出现 “There is no active transaction” 的异常信息

线上有一些业务代码偶尔会抛出事务提交失败,经过排查之后,锁定问题点如下,虽然可以从业务从避免,但是还是想知道一下原因。

  1. 数据库需要是 Polardb(mysql 没有问题)
  2. 需要是新连接
  3. 事务开启之后只有读的操作 然后就提交 OR 回滚
  4. 少量读容易抛异常,大量读的情况下偶尔会有异常?(待确定)
// 业务代码模拟
public function test()
{
    Db::beginTransaction();
    // 随便的一些查询
     Db::table('system_admin')->where('id',1)->value('username');
    // if然后就没执行更新或者插入
     Db::commit();
}

// Hyperf\DbConnection\Connection
public  function  getActiveConnection(): DbConnectionInterface

 { 
     // 让其必定触发reconnect()
     // if ($this->check()) {
    //      return $this;
    // }
     if  (! $this->reconnect())  {
         throw  new  ConnectionException('Connection reconnect failed.');
     }
     return  $this;

 }

追加防喷 Buff

小菜鸟一个,我只是好奇问题本身,请不用衍生到一些别的问题;如果开杠,杠就是你对

问题本身追查部分细节

  • 事务有没有成功开启
    • 用 Hyperf 的事件监听确定开启了
    • 利用 Hyperf 框架的 isTransaction () 确定 commit 的时候 transactions = 1
    • 确定 commit 只执行了一次
  • 追查问题点
    • 一通操作之后,经过对比发现了服务重启的时候容易异常
    • 最后追查到新链接的时候必定抛出问题

猜测
Polardb 自身初始化的时候,我只读取,所以走到了读库,commit 的时候异常了
之后再操作的时候,hyperf 的 mysql 连接未销毁,commit 没问题可能是 Polardb 自身的一些机制问题
切换读写了?

  • 多次读的时候偶尔异常的原因
    • 通过 Db::getPdo ()->inTransaction () 的时候
    • 第一次读的时候必定是 false
    • 后续读有的时候是 true,有的时候 false

* 写问题的时候很困了,因为不能影响线上,都是晚上空闲的时候慢慢摸的,摸了几天,所以语序有点乱,如果有人追问的话可能会补充点细节,就酱 *

最佳答案

根本问题是连接地址的事务一致性问题。

file

选会话一致即可。

2年前 评论
令龙家的小道 (楼主) 2年前
讨论数量: 9

根本问题是连接地址的事务一致性问题。

file

选会话一致即可。

2年前 评论
令龙家的小道 (楼主) 2年前
李铭昕

新连接出问题?发一下 Hyperf 版本号,我记得 PHP8 有个版本的 PDO 会有点问题,容易在这时候出现问题。

2年前 评论
令龙家的小道 (楼主) 2年前
李铭昕 (作者) 2年前
令龙家的小道 (楼主) 2年前
李铭昕 (作者) 2年前
令龙家的小道 (楼主) 2年前
令龙家的小道 (楼主) 2年前