sogou / workflow

C++ Parallel Computing and Asynchronous Networking Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

关于mysql事务的回滚问题

Cyber-SiKu opened this issue · comments

commented

使用方法类似于下面这样:

WFMySQLTask *begin_task =
        connection_->create_query_task(SqlTask::BEGIN.getQuery(), SqlTask::BEGIN.getCallBack());
    begin_task->set_wait_timeout(wait_timeout);
    SeriesWork* series(Workflow::create_series_work(begin_task, series_callback_));
    for (auto const &task : tasks_) {
// task是预设值的一系列task包括sql语句和回调函数
        auto *sql_task = connection_->create_query_task(task.getQuery(), task.getCallBack());
        sql_task->set_wait_timeout(wait_timeout);
        if(task.getUserData()!=nullptr){
            sql_task->user_data = task.getUserData();
        }
        series->push_back(sql_task,is_thread_safe);
    }
    WFMySQLTask *commit_task =
        connection_->create_query_task(SqlTask::COMMIT.getQuery(), SqlTask::COMMIT.getCallBack());
    commit_task->set_wait_timeout(wait_timeout);
    series->push_back(commit_task,is_thread_safe);
    WFMySQLTask *disconnect = connection_->create_disconnect_task(SqlTask::DISCONNECT_CALLBACK);
    disconnect->set_wait_timeout(wait_timeout);
    series->push_back(disconnect,is_thread_safe);
// 设置 series的回调函数
series->start()

series的回调函数中会判断series是否是取消的如果是取消的会主动发送rollback 类似于下面这样:

// series 回调函数中
            if(series->is_canceled()) {
                txn->rollback(); // txn 类型是 SqlTransaction
            }

void SqlTransaction::rollback() {
    WFMySQLTask *rollback_task = connection_->create_query_task(SqlTask::ROLLBACK.getQuery(),
                                                                SqlTask::ROLLBACK.getCallBack());
    rollback_task->start();
}

会导致程序崩溃,崩溃的调用栈类似于下面这样:
image
调试是执行到下面部分崩溃:
企业微信截图_37dbdde3-d0e7-4dec-978b-563c0bf47c29

你好。你使用的代码有点旧了。这个bug应该一年前左右修复的。最新的实现是这样的:

    if (this->is_fixed_addr())
    {
        if (this->state != WFT_STATE_SUCCESS || this->keep_alive_timeo == 0)
        {
            if (this->target)
                ((RouteManager::RouteTarget *)this->target)->state = 0;
        }
    }

这个的触发条件也比较难。你先更新到最新代码试一下吧,看看是不是就解决了你的问题。

commented

你好。你使用的代码有点旧了。这个bug应该一年前左右修复的。最新的实现是这样的:

    if (this->is_fixed_addr())
    {
        if (this->state != WFT_STATE_SUCCESS || this->keep_alive_timeo == 0)
        {
            if (this->target)
                ((RouteManager::RouteTarget *)this->target)->state = 0;
        }
    }

这个的触发条件也比较难。你先更新到最新代码试一下吧,看看是不是就解决了你的问题。

thanks,我试一下。

commented

你好。你使用的代码有点旧了。这个bug应该一年前左右修复的。最新的实现是这样的:

    if (this->is_fixed_addr())
    {
        if (this->state != WFT_STATE_SUCCESS || this->keep_alive_timeo == 0)
        {
            if (this->target)
                ((RouteManager::RouteTarget *)this->target)->state = 0;
        }
    }

这个的触发条件也比较难。你先更新到最新代码试一下吧,看看是不是就解决了你的问题。

可以了!