swoft-cloud / swoft

🚀 PHP Microservice Full Coroutine Framework
https://swoft.org
Apache License 2.0
5.58k stars 786 forks source link

swoft2.x 连接池mysql事务问题 #896

Closed MrCJJW closed 5 years ago

MrCJJW commented 5 years ago
Q A
Bug report? yes
Feature request? no
Swoft version 2.x
Swoole version 4.4.3
PHP version 7.3.8
Runtime environment Docker

Details

在一个事务中,连接断线的情况下,事务失败,断线前的sql执行不成功,断线重连后的sql执行成功,并不能保证事务

string(30) "There is no active transaction"
2019/08/13-21:00:53 [ERROR] App\Exception\Handler\HttpExceptionHandler:handle(36) There is no active transaction

Provide minimal script to reproduce the issue

    /**
     * @RequestMapping("test")
     */
    public function test()
    {
        Swoft\Db\DB::beginTransaction();
        try {
            Swoft\Db\DB::table('user')->where('id', 1)->update(['name' => 2]);
            Swoft\Co::sleep(5);// 模拟慢查询,此时在navicat手动断开mysql连接
            Swoft\Db\DB::table('address')->where('id', 1)->update(['address' => 2]);
            Swoft\Db\DB::commit();
        } catch (\Exception $e) {
            var_dump($e->getMessage());
            Swoft\Db\DB::rollBack();
        }
    }

建议在捕捉到断线的异常时,还需要判断下该协程是否在事务环境下,如果是的话就不要重新进行sql操作,直接抛出异常

Connection\Connection.php
protected function runQueryCallback(){}

该方法会在捕捉到错误时重新执行sql

stelin commented 5 years ago

@MrCJJW 这是一个非常好的issue,我修复下这个问题,感谢对 Swoft 的支持。

stelin commented 5 years ago

@MrCJJW 已修复 2.0.6 一起发布。

MrCJJW commented 5 years ago

可以贴一下具体哪个commit吗,没找着😅,谢谢

stelin commented 5 years ago

https://github.com/swoft-cloud/swoft-component/pull/507/commits/c2e87f278815fd14dbccb71d5f6a63d4f974d38b