Нужно ли писать ROLLBACK, если запросы не выполняются? - PullRequest
8 голосов
/ 01 мая 2010

пишу

mysql_query("SET AUTOCOMMIT=0");
mysql_query("START TRANSACTION");

прежде чем я напишу все запросы. Затем проверьте, все ли они верны, и напишите:

mysql_query("COMMIT");

Но если один из запросов не выполняется, я просто передаю запрос COMMIT. Так действительно ли мне нужна функция ROLLBACK в случае сбоя одного из запросов? Потому что без ROLLBACK это тоже работает.
Благодаря.

Ответы [ 5 ]

12 голосов
/ 01 мая 2010

Я думаю, вы спрашиваете, нужно ли выполнять ROLLBACK, так как без него коммиты по-прежнему не применяются. Это технически верно, но только потому, что транзакция все еще открыта, поскольку вы ее еще не завершили. Все, что неявно фиксирует транзакцию (например, запускает новую транзакцию), будет действовать так, как будто вы запустили COMMIT, что противоположно тому, что вы хотите

5 голосов
/ 01 мая 2010

Причина использования транзакций состоит в том, чтобы сгруппировать несколько изменений вместе, чтобы все они выполнялись атомарно, иначе, если они не могут, не делайте ни одного из них. Другими словами, если какое-либо изменение завершится неудачно, транзакция оставит базу данных в логически несовместимом состоянии.

Пример: дебетование одной учетной записи в одном ОБНОВЛЕНИИ и кредитование другого счета в отдельном ОБНОВЛЕНИИ. Это представляет собой перевод денег. Если дебет завершился успешно, но кредит потерпел неудачу, вы должны откатить всю транзакцию, иначе окажется, что деньги исчезли из воздуха.

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

Кажется, вы говорите, что в вашем приложении все в порядке, если одно из изменений не выполнено. Это заставляет меня думать, что вы сгруппировали изменения в транзакции ненадлежащим образом.

Решите, какая группа изменений должна все удастся выполнить вместе, и поместите их в одну транзакцию. Любые изменения, не относящиеся к этой группе, должны быть в отдельной транзакции.

1 голос
/ 02 мая 2010

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

Кроме того, если транзакция получила какие-либо блокировки, эти блокировки все еще остаются активными до тех пор, пока что-то не вызовет откат или не уничтожит соединение (что является автооткатом). Вы можете в конечном итоге вызвать застревание журнала для любых других запросов, если они касаются заблокированных таблиц / строк.

1 голос
/ 02 мая 2010

Это зависит от того, как вы делаете обработку ошибок в целом. Использование транзакций - это хорошо, потому что, если ваш код внутри транзакции выдает исключение (которое может ИЛИ НЕ МОЖЕТ быть из-за сбоя запроса к базе данных), обычно ваш обработчик исключений вызовет откат.

Более того, если вы закрыли соединение без фиксации, например, из-за неожиданного завершения процесса, откат произойдет неявно, что, как правило, хорошо (повышает надежность, поскольку при перезапуске процесса он может повторить попытку)

Теперь, конечно, использование PHP и «старого» mysql API не способствует получению этого права, так как он не поддерживает сообщения об ошибках по исключениям.

Однако вы можете обойти это, зарегистрировав обработчик ошибок PHP, который выдает исключение при возникновении ошибки, вместо того, чтобы выполнить метод «начисления платы за бедствие» по умолчанию:

"Captain, we've hit an iceberg
"Full steam ahead, put more coal in, we'll get to new york soon...
1 голос
/ 01 мая 2010

Вы должны явно использовать ROLLBACK, чтобы прояснить, что вы делаете, любому, кто будет читать ваш код позже, а может быть и вам:)

Кроме того, если вы добавляете код, который должен выполняться после COMMIT / ROLLBACK, лучше инициировать его явно, чтобы иметь более предсказуемое состояние ваших данных. Если вы полагаетесь на auto-ROLLBACK, этот код может ожидать, что база данных будет в неизмененном состоянии, пока она еще находится в незафиксированной транзакции.

...