如何使用 PHP 的预处理语句和 MySQL 的事务执行多个查询?
How to execute multiply queries using PHP's prepared statemens with MySQL's transaction?
我需要使用 PHP 的准备语句和 MySQL 的事务执行 2 个或更多不相同的查询(在本例中为 INSERT
。)。因此,如果我有 2 个 INSERT
语句,我希望它们都被执行,或者它们中的 none 个被执行。
我想将此示例 MySQL 交易翻译成 PHP 代码:
START TRANSACTION;
INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES ('file.png', 'image/png', '1024', 'My comment');
INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (LAST_INSERT_ID(), '1');
COMMIT;
PHP 我正在处理的代码:
mysqli_autocommit($connection, FALSE);
if ($stmtFile = mysqli_prepare($connection, "INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES (?, ?, ?, ?)")) {
mysqli_stmt_bind_param($stmtFile, 'ssis', $name, $mime_type, $size, $comment);
if (mysqli_stmt_execute($stmtFile)) {
if ($stmtComplementaryFile = mysqli_prepare($connection, "INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (?, ?)")) {
mysqli_stmt_bind_param($stmtComplementaryFile, 'ii', mysqli_insert_id($connection), $user_id);
mysqli_stmt_execute($stmtComplementaryFile);
}
} else {
mysqli_rollback($connection);
}
}
mysqli_commit($connection);
PHP 上面的代码可以工作,但是如果我有更多的关键语句要执行怎么办?有没有什么好的方法可以同时使用 PHP 准备好的语句 和 事务执行语句?
请注意,对于 $stmtComplementaryFile
,我必须有一个 mysqli_insert_id()
值。另请注意,我没有将 PDO 与此代码一起使用 — 如果建议是 MySQLi,我将不胜感激。谢谢。
以下SQL:
START TRANSACTION;
INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES ('file.png', 'image/png', '1024', 'My comment');
INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (LAST_INSERT_ID(), '1');
COMMIT;
可以转换为PHP(使用预处理语句)如下:
mysqli_begin_transaction($connection, MYSQLI_TRANS_START_READ_WRITE);
if ($stmtFile = mysqli_prepare($connection, "INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES (?, ?, ?, ?)")) {
mysqli_stmt_bind_param($stmtFile, 'ssis', $name, $mime_type, $size, $comment);
if (mysqli_stmt_execute($stmtFile)) {
if ($stmtComplementaryFile = mysqli_prepare($connection, "INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (?, ?)")) {
mysqli_stmt_bind_param($stmtComplementaryFile, 'ii', mysqli_insert_id($connection), $user_id);
mysqli_stmt_execute($stmtComplementaryFile);
}
} else {
mysqli_rollback($connection);
}
}
mysqli_commit($connection);
一般来说,这两个语句是等价的,但是最好知道什么是交易,什么不是交易。
事务是一种机制,可确保批量操作以原子方式执行,并且只有当所有操作都成功时,它们的结果才会反映在数据库中。它确保 atomicity
的操作。
事务不是在 table 上实现互斥锁的机制。如果需要锁定 table,则需要使用 LOCK TABLES [READ|WRITE]
。等效地在 PHP 中,这是通过执行以下操作实现的:
mysqli_query($connection, "LOCK TABLES tableName as TableAlias [read|write]");
接着是
mysqli_query($connection, "UNLOCK TABLES");
我需要使用 PHP 的准备语句和 MySQL 的事务执行 2 个或更多不相同的查询(在本例中为 INSERT
。)。因此,如果我有 2 个 INSERT
语句,我希望它们都被执行,或者它们中的 none 个被执行。
我想将此示例 MySQL 交易翻译成 PHP 代码:
START TRANSACTION;
INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES ('file.png', 'image/png', '1024', 'My comment');
INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (LAST_INSERT_ID(), '1');
COMMIT;
PHP 我正在处理的代码:
mysqli_autocommit($connection, FALSE);
if ($stmtFile = mysqli_prepare($connection, "INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES (?, ?, ?, ?)")) {
mysqli_stmt_bind_param($stmtFile, 'ssis', $name, $mime_type, $size, $comment);
if (mysqli_stmt_execute($stmtFile)) {
if ($stmtComplementaryFile = mysqli_prepare($connection, "INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (?, ?)")) {
mysqli_stmt_bind_param($stmtComplementaryFile, 'ii', mysqli_insert_id($connection), $user_id);
mysqli_stmt_execute($stmtComplementaryFile);
}
} else {
mysqli_rollback($connection);
}
}
mysqli_commit($connection);
PHP 上面的代码可以工作,但是如果我有更多的关键语句要执行怎么办?有没有什么好的方法可以同时使用 PHP 准备好的语句 和 事务执行语句?
请注意,对于 $stmtComplementaryFile
,我必须有一个 mysqli_insert_id()
值。另请注意,我没有将 PDO 与此代码一起使用 — 如果建议是 MySQLi,我将不胜感激。谢谢。
以下SQL:
START TRANSACTION;
INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES ('file.png', 'image/png', '1024', 'My comment');
INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (LAST_INSERT_ID(), '1');
COMMIT;
可以转换为PHP(使用预处理语句)如下:
mysqli_begin_transaction($connection, MYSQLI_TRANS_START_READ_WRITE);
if ($stmtFile = mysqli_prepare($connection, "INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES (?, ?, ?, ?)")) {
mysqli_stmt_bind_param($stmtFile, 'ssis', $name, $mime_type, $size, $comment);
if (mysqli_stmt_execute($stmtFile)) {
if ($stmtComplementaryFile = mysqli_prepare($connection, "INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (?, ?)")) {
mysqli_stmt_bind_param($stmtComplementaryFile, 'ii', mysqli_insert_id($connection), $user_id);
mysqli_stmt_execute($stmtComplementaryFile);
}
} else {
mysqli_rollback($connection);
}
}
mysqli_commit($connection);
一般来说,这两个语句是等价的,但是最好知道什么是交易,什么不是交易。
事务是一种机制,可确保批量操作以原子方式执行,并且只有当所有操作都成功时,它们的结果才会反映在数据库中。它确保 atomicity
的操作。
事务不是在 table 上实现互斥锁的机制。如果需要锁定 table,则需要使用 LOCK TABLES [READ|WRITE]
。等效地在 PHP 中,这是通过执行以下操作实现的:
mysqli_query($connection, "LOCK TABLES tableName as TableAlias [read|write]");
接着是
mysqli_query($connection, "UNLOCK TABLES");