webman mysql 多进程 死锁

workers

问题描述

报错:【SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction】

webman的项目,偶尔报这个错误,经检查代码里并没有使用事务,请问下:webman的多进程模型,并发高的时候是否可能出现操作同一数据表时发生死锁的情况?
这种情况该怎么解决了
webman版本1.4.3
webman/think-orm 1.0
截图

1923 4 1
4个回答

evilk
  • workers 2023-05-25

    我代码里面并没有用到事务呀

  • evilk 2023-05-25

    可以装一下webman官方的日志插件
    里面有一段代码是"判断Db是否有未提交的事务"
    可以先尝试一下
    // 判断Db是否有未提交的事务 $has_uncommitted_transaction = false; if (class_exists(Connection::class, false)) { if ($log = $this->checkDbUncommittedTransaction()) { $has_uncommitted_transaction = true; $method = 'error'; $logs .= $log; } }

小W

我前两天也遇到了,就是事务未提交或者回滚导致的死锁

  • workers 2023-05-25

    我代码里面并没有用到事务呀

nitron

存在unique索引的表在多进程INSERT的时候,即使不用事务也会出现deadlock的,而且这是最容易复现的

因为单个语句的操作,也是一个事务,只是不用显式的begin/commit/rolback transaction而已

  • workers 2023-05-25

    看报错请求的trace 定位的是一条查询语句
    ModelLeave::update(array("reads" => $v['reads'] . $member['id'] . ','), ['id' => $v['id']]);
    但是从我业务逻辑上分析 这个修改应该只会有一个人,也就是一个进程来操作 不应该会出现并发情况。

  • tanhongbin 2023-05-25

    没遇到过,多进程同时处理也不会出现死锁呀,update自带排它锁,你是按照主键修改的嘛?

  • workers 2023-05-25

    是按照主键修改的

  • tanhongbin 2023-05-25

    那不应该呀,按照主键修改 都是自带排它锁的,不应该出现死锁呀

  • 小W 2023-05-25

    update之前会不会就已经死锁了

  • tanhongbin 2023-05-25

    这个有可能呀,楼主还得自己排查一下

  • workers 2023-05-25

    不会是因为update之前死锁的 刚又出现了一次 是另一个方法 里面只有三行sql查询
    $is = Distance::where([['name', '=', $member['name']]])->findOrEmpty()->toArray();
    if ($is) {
    Distance::where([['id', '=', $is['id']]])->update(array('name' => $member['name'], 'lat' => $lat, 'lon' => $lon, 'res' => $distance, 'addtime' => date('Y-m-d H:i:s')));
    } else {
    Distance::create(array('name' => $member['name'], 'lat' => $lat, 'lon' => $lon, 'res' => $distance, 'addtime' => date('Y-m-d H:i:s')));
    }
    其中update那行又报死锁错误了

  • tanhongbin 2023-05-25

    这里的name 是不是唯一索引??

  • workers 2023-05-25

    name不是唯一索引,id是主键,innodb表,没有任何索引

  • tanhongbin 2023-05-25

    你得在检查一下是否 其他方法中有事务没有提交,同一个进程 一个mysql连接,会影响其他方法

  • tanhongbin 2023-05-25

    例如方法出现bug导致 事务开启后 报错代码停止了,这个时候事务就是没有提交,会导致当前进程 所有方法 中的事务等待,会显示超时,所以最好在使用事务时候,使用try catch

  • nitron 2023-05-25

    查MSQL的日志看吧,空对空没意义

meows

这个问题和thinkorm webman 没任何关系,仅仅是你SQL语句写的有问题。
这种错误“QLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction”,
本质含义,开启事务长时间未提交,大概率有记录被锁住,没有办法被提交释放锁,导致这个事务被撤销。
你没有开启事务,但是INNODB默认会开启事务。
你应该bing.com 搜索“mysql 死锁 事务长时间超时撤销”关键词去找一下答案,你要定位到引起锁的SQL语句是什么,然后分析原因。你这样报告thinkorm webman 版本没太多意义,这个问题不是这两个引起的。

  • 暂无评论
年代过于久远,无法发表回答
×
🔝