我遇到一个问题,即准备好的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,因此应该提供事务支持。我真的不知道下一步该尝试什么。
答案 0 :(得分:0)
找到它 - 看起来如果你不消耗所有的结果集,那么事务似乎最终会回滚。存储过程调用会将空结果集添加为最后一个结果集,以便发生了什么。
// ...
$row = $stmt->fetch();
// let's consume all resultsets
while($stmt->nextRowset() && $stmt->columnCount());
$sol->db->commit();
// ...