添加select语句时mysqli_commit失败

时间:2016-09-02 08:50:47

标签: php mysql mysqli

问题:

无法使用mysqli_begin_transaction将mySQL存储过程存储数据。

详细信息:

下面的代码将使用mysql存储过程执行简单的insertselect。代码运行良好没有 select语句。但是,一旦添加了select语句,即使查询在PHP端返回成功,它也不会提交任何数据。

代码段(PHP):

$DB_DRRM_SQLI = mysqli_connect("localhost","root","", "sandbox_db");
mysqli_begin_transaction($DB_DRRM_SQLI);

$SQL_QUERY_CODE = "CALL SANDBOX_TEST()";
$DB_QUERY = mysqli_query($DB_DRRM_SQLI, $SQL_QUERY_CODE);


// ERROR REPORTING
if($DB_QUERY === false)
{
    echo mysqli_error($DB_DRRM_SQLI);
    mysqli_rollback($DB_DRRM_SQLI);
}
else
{
    echo 'success';
    mysqli_commit($DB_DRRM_SQLI);
}
exit;

代码段(mySQL存储过程):

BEGIN
    INSERT INTO 
    `sandbox_table`
    (
        `SOME_STRING`
    )
    VALUES
    (
        'ABCDEFGHIJKL...'
    );

    SELECT 
        LAST_INSERT_ID() AS INSERTED_ID,
        'ABCDE...' AS OTHER_PARAMS; 
END

数据库(表sandbox_table):

  1. RECORD_PRIMARY_ID( Int - 自动增量
  2. SOME_STRING( Varchar - 500长度
  3. 规格:

    • PHP版本:5.6.14
    • 10.1.8-MariaDB的
    • 存储引擎: InnoDB

    备注:

    • 如果在存储过程中进行事务工作正常,但我需要一个PHP托管事务来处理多个查询请求和响应,具体取决于查询结果。
    • (如果没有其他解决方案,我需要将整个PHP代码转换为存储过程并需要传递大量参数,这可能是最后的手段)

    测试的方法:

    • 尝试使用其他PHP版本7.0.9,结果相同(10.1.16-MariaDB)
    • 使用新数据库进行测试,除sandbox_table及以上存储过程外没有其他数据。
    • 在没有额外包含库的情况下进行测试(仅在上面的代码段上进行测试)。

1 个答案:

答案 0 :(得分:0)

<强>解决方案:

这是由mysqli_commit处的命令不同步错误引起的。似乎 mysqli 在查询打开时不允许提交事务,如果将select语句添加到上述存储过程,则会发生这种情况。

因此,要处理此问题,必须先关闭查询或将查询置于缓冲区。

代码段(PHP):

// SQL Database
$DB_DRRM_SQLI = mysqli_connect("localhost","root","", "sandbox_db");
mysqli_begin_transaction($DB_DRRM_SQLI);

$SQL_QUERY_CODE = "CALL SANDBOX_TEST()";
$DB_QUERY = mysqli_query($DB_DRRM_SQLI, $SQL_QUERY_CODE);

// ERROR REPORTING
if($DB_QUERY === false)
{
    echo mysqli_error($DB_DRRM_SQLI);
    mysqli_rollback($DB_DRRM_SQLI);
}
else
{
    // Must free current query result before committing transaction
    @mysqli_free_result($DB_QUERY);
    @mysqli_next_result($DB_DRRM_SQLI);

    if(mysqli_commit($DB_DRRM_SQLI) === false)
    {
        echo mysqli_error($DB_DRRM_SQLI);
    }
    else
    {
        echo 'success';
    }
}
exit;