Как справиться с тупиковой ситуацией MySQL ситуации на уровне приложения?

Когда в 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;

В этой ситуации я не могу просто повторно выполнить транзакцию в том виде, в котором она была изначально создана. ID, полученный первым оператором SQL, больше не действителен после сбоя транзакции, но используется вторым оператором. Между тем, многие объекты были заполнены данными из транзакции, которые затем устаревают, когда транзакция откатывается.Сам код приложения, конечно, не "откатывается" вместе с базой данных.

Вопрос: как я могу справиться с этими ситуациями в коде приложения? (PHP)

Я предполагаю две вещи. Скажите, пожалуйста, если вы думаете, что я на правильном пути:

1) Поскольку база данных не может просто дословно перевыпустить транзакцию во всех ситуациях, мое исходное решение не работает и не должно использоваться.

2) Единственный хороший способ сделать это - обернуть весь код, выдающий транзакцию, в его собственный блок try / catch и попытаться перевыпустить сам код, а не только SQL.

Спасибо за ваш вклад. Ты жжешь.

17
задан leiavoia 11 November 2011 в 21:06
поделиться