PHP MySQL InnoDB: несколько вставок в разные таблицы с использованием сбоев транзакций

Я изучал транзакции и, насколько я понимаю, мой оператор множественной вставки должен работать.

Я использую движок InnoDB. Оба оператора вставки, приведенные ниже, работают и правильно вводят данные в соответствующие таблицы, но только если у меня есть один из них одновременно в транзакции, а не оба вместе.

Может ли кто-нибудь сказать мне, что мне нужно делать по-другому?

Не работает с Affected rows (INSERT): -1

код:

$con->begin_transaction();

$con->autocommit(FALSE);


$query = "

INSERT INTO `Order` (`PO`,`SellingManagerSalesRecordNumber`,`OrderID`,
  `AmountPaid`,`CreatedTime`,`Subtotal`,`Total`,`BuyerUserID`,
  `IsMultiLegShipping`,`Status_id`,`SellerUserID_id`)
   VALUES
   ('AF11514','11514','111809902234-1906167668001','55.98',
  '2019-01-07 17:42:46','55.98','55.98','hyccas3','false',
   (SELECT `id` FROM `Status` WHERE `Status` = 'Completed'),
   (SELECT `id` FROM `SellerUserID` WHERE `SellerUserID` = 'afiperformance'))
   ON DUPLICATE KEY UPDATE PO = VALUES(PO),
   SellingManagerSalesRecordNumber = VALUES(SellingManagerSalesRecordNumber),
   OrderID = VALUES(OrderID),
   AmountPaid = VALUES(AmountPaid),
   CreatedTime = VALUES(CreatedTime), Subtotal = VALUES(Subtotal),
   Total = VALUES(Total),
   BuyerUserID = VALUES(BuyerUserID),
   IsMultiLegShipping = VALUES(IsMultiLegShipping);

INSERT INTO `CheckoutStatus` (`PO`,`LastModifiedTime`, 
         `PaymentMethod_id`,`Status_id`)
   VALUES ('AF11514','2019-01-07 17:47:55',
  (SELECT `id` FROM `PaymentMethod` WHERE `PaymentMethod` = 'PayPal'),
   (SELECT `id` FROM `Status` WHERE `Status` = 'Complete'))
   ON DUPLICATE KEY UPDATE PO = VALUES(PO),
   LastModifiedTime = VALUES(LastModifiedTime);";

echo $query;

$con->query($query);
printf("<br><br>\n\nAffected rows (INSERT): %d ", $con->affected_rows) . "\n\n<br><br>";

if ($con->affected_rows == -1) {
    echo "<br><br>\n\n Failed " . "\n\n<br><br>";
    $con->rollback();
    $commit = '';
} else {
    $commit = $con->commit();
    echo " success " . "\n\n<br><br>";
}

/* commit transaction */
if ($commit == '') {
    print("Transaction commit failed\n");
} else {
    print("Transaction commit success\n");
}

$con->close();
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
175
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

mysqli_query не поддерживает несколько запросов за один вызов. Вам нужно либо использовать mysqli_multi_query, либо разделить запрос на два отдельных вызова mysqli_query. Поскольку вы используете транзакции, было бы лучше разделить вызовы на два, поскольку получить информацию об ошибках для второго и последующих запросов в mysqli_multi_query сложно.

Тогда мне все еще нужно использовать транзакции? Или достаточно mysqli_multi_query?

Mike 10.01.2019 07:46

Нет. Просто звоните mysqli_query по одному оператору за раз.

Rick James 10.01.2019 07:49

@Mike вызов mysqli_multi_query не эквивалентен использованию транзакций. Вы все равно должны их использовать.

Nick 10.01.2019 07:52

@RickJames, вы говорите, поместите каждый оператор SQL в отдельный $con->query();, верно? Я делал это так, и это сработало, но я думал, что транзакции отправляют все данные сразу, и если я отправляю их по одному в собственном $con->query();, то кажется, что я побеждаю цель использования транзакций?

Mike 10.01.2019 08:00

@Mike совсем нет, смысл использования транзакций в том, чтобы позволить вам откатить эффект транзакций, если какая-либо из них не удалась.

Nick 10.01.2019 08:02

Если вы начнете транзакцию, все последующие операторы будут частью этой транзакции, пока вы не зафиксируете или не откатитесь. Вам не нужно отправлять отчеты за один звонок. Фактически, у вас может не получиться, если вам нужно выполнить больше операторов SQL в одной транзакции, чем может поместиться в один пакет. Верхнего предела количества операторов в одной транзакции нет, но есть верхний предел размера одного пакета.

Bill Karwin 10.01.2019 20:06

Бывший технический директор MySQL сказал мне: «В буквальном смысле нет причин для существования множественных запросов».

Bill Karwin 10.01.2019 20:07

И создатель PHP сказал: «Не используйте его». Если вы это допускаете, вы просто даете хакеру еще один (довольно простой) способ проникнуть в вашу систему.

Rick James 10.01.2019 23:47

Другие вопросы по теме