准备好的PDO MySQL语句提交,但更改不会粘贴

时间:2017-05-02 20:40:25

标签: php mysql pdo

我遇到一个问题,即准备好的MySQL存储过程调用在事务中运行良好,我看到了存储过程的预期结果,但是这些更改似乎没有保存到实际的数据库中。

PHP的一面看起来像这样:

$options = array();
$db = new PDO("mysql:host=localhost;dbname=mydb", "myuser", "mypass", $options);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

// ..... .... ... .. .

$response["error"] = true;
if ($db->beginTransaction() == true)
{
    try
    {
        $stmt = $db->prepare("call Layout_Row_Add(:pageid, :position);");
        // $jason->page_id
        $stmt->bindValue(':pageid', (int)$jason->page_id, PDO::PARAM_INT);
        // $jason->position
        $stmt->bindValue(':position', (int)$jason->position, PDO::PARAM_INT);
        $stmt->execute();
        $response["dbg1"] = $jason->page_id;
        $response["dbg2"] = $jason->position;
        $response["intrans1"] = $db->inTransaction();
        $row = $stmt->fetch();
        $db->commit();
        $response["intrans2"] = $db->inTransaction();           
        $response["new_row_id"] = $row["NewRowId"];
        $response["error"] = false;
    }
    catch (PDOException $e)
    {
        $db->rollBack();
        $response["errortext"] = "PDO exception: " . $e->getMessage();
    }
    catch (Exception $exc)
    {
        $db->rollBack();
        $response["errortext"] = "Exception: " . $e->getMessage();
    }       
}
else            
{
    $response["errortext"] = "Couldn't start transaction";
}

$response变量被编码为JSON并发送回浏览器,从而得到:

error       false
dbg1        1
dbg2        3
intrans1    true
intrans2    false
new_row_id  21  

所有内容看起来都应该是这样,new_row_id处于预期值,意味着自动增量字段已填满,调试字段和交易信息也符合预期。

但是,在MySQL Workbench中执行select *不会返回任何假定由该过程添加的行。在MySQL Workbench中运行程序本身工作正常,因为提交实际上很棒。这是程序本身:

CREATE DEFINER=`myuser`@`myhost` PROCEDURE `Layout_Row_Add`(PageId int, Position int)
BEGIN
    declare NewRowId int unsigned default 0;
    update pages_layout_rows set ordinal = ordinal + 1 where page_id = PageId and ordinal >= Position;
    insert into pages_layout_rows (page_id, ordinal) values (PageId, Position);
    set NewRowId = last_insert_id();
    select NewRowId; 
END

该表设置为InnoDB,因此应该提供事务支持。我真的不知道下一步该尝试什么。

1 个答案:

答案 0 :(得分:0)

找到它 - 看起来如果你不消耗所有的结果集,那么事务似乎最终会回滚。存储过程调用会将空结果集添加为最后一个结果集,以便发生了什么。

// ...
$row = $stmt->fetch();
// let's consume all resultsets
while($stmt->nextRowset() && $stmt->columnCount());
$sol->db->commit();
// ...