準備されたMySQLストアドプロシージャコールがトランザクションで正常に実行され、ストアドプロシージャの予想される結果が表示されますが、実際のデータベースに保存します。Prepared 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に設定されているため、トランザクションサポートが利用可能になっているはずです。私は次に何を試すべきか分からない。
なぜストアドプロシージャを使用するのですか?最悪のシナリオでは、代わりにPHPにクエリを置くことができますか? – NobleUplift
また、 '$ db-> commit();'の後に '$ row = $ stmt-> fetch();'を移動して、トランザクションの外に出ているものを見てください。 – NobleUplift
フェッチを移動しても効果はありませんでした。ステートメントのハードコーディングは更新を行いますが、主にカプセル化のためにストアドプロシージャを使用することをお勧めします。 – varius