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

选会话一致即可。

3个月前 评论
令龙小道 (楼主) 3个月前
讨论数量: 9

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

file

选会话一致即可。

3个月前 评论
令龙小道 (楼主) 3个月前
李铭昕

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

3个月前 评论
令龙小道 (楼主) 3个月前
李铭昕 (作者) 3个月前
令龙小道 (楼主) 3个月前
李铭昕 (作者) 3个月前
令龙小道 (楼主) 3个月前
令龙小道 (楼主) 3个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!