Действительно ли необходимо записать ОТКАТ, если запросы перестали работать?

Я пишу

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

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

mysql_query("COMMIT");

Но если один из сбоев запроса, я просто передаю запрос ФИКСАЦИИ. Я действительно должен ОТКАТЫВАТЬ функцию, если один из запросов перестал работать? Поскольку без ОТКАТА это также работает.
Спасибо.

8
задан good_evening 1 May 2010 в 18:40
поделиться

5 ответов

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

.
12
ответ дан 5 December 2019 в 07:57
поделиться

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

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

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

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

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

6
ответ дан 5 December 2019 в 07:57
поделиться

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

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

1
ответ дан 5 December 2019 в 07:57
поделиться

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

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

1
ответ дан 5 December 2019 в 07:57
поделиться

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

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

Конечно, использование PHP и "старого" API mysql не способствует достижению этой цели, поскольку он не поддерживает отчет об ошибках с помощью исключений.

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

"Captain, we've hit an iceberg
"Full steam ahead, put more coal in, we'll get to new york soon...
1
ответ дан 5 December 2019 в 07:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: