Когда возникает ситуация взаимоблокировки в MySQL / InnoDB, он возвращает эту знакомую ошибку:
'Обнаружен тупик при попытке получить блокировку; попробуйте перезапустить транзакцию '
Итак, я сделал запись всех запросов, которые входят в транзакцию, чтобы их можно было просто переиздать в случае сбоя оператора в транзакции. Простой.
Проблема: если у вас есть запросы, которые зависят от результатов предыдущих запросов, это не так хорошо работает.
Например:
START TRANSACTION;
INSERT INTO some_table ...;
-- Application here gets ID of thing inserted: $id = $database->LastInsertedID()
INSERT INTO some_other_table (id,data) VALUES ($id,'foo');
COMMIT;
В этой ситуации я не могу просто переиздать транзакцию, как она была изначально создана. Идентификатор, полученный первым оператором SQL, больше не действителен после сбоя транзакции, но используется вторым оператором. Между тем, многие объекты были заполнены данными из транзакции, которые затем становятся устаревшими при откате транзакции. Сам код приложения, конечно, не «откатывается» с базой данных.
Вопрос: как я могу справиться с этими ситуациями в коде приложения? (PHP)
Я предполагаю две вещи. Скажите, пожалуйста, если вы считаете, что я на правильном пути:
1) Поскольку база данных не может просто переписать транзакцию дословно во всех ситуациях, мое оригинальное решение не работает и не должно использоваться.
2) Единственный хороший способ сделать это - обернуть любой и весь код выдачи транзакции в собственный блок try / catch и попытаться переиздать сам код, а не только SQL.
Спасибо за ваш вклад. Вы качаетесь.