MySQL Как правильно использовать транзакции? - PullRequest
0 голосов
/ 31 января 2019

Я сталкиваюсь в своем проекте с необходимостью реализации транзакций, чего раньше никогда не делал.Я уже проверил, что мой aytocommit установлен на 1 - и я не уверен, что мне вообще нужно его трогать?

Сейчас у меня есть набор сценариев, которые все включают функцию, которая сначала подключается к базе данных.Есть идеальное место для размещения mysqli_begin_transaction($link); и mysqli_autocommit($link, FALSE);, так что я буду иметь транзакции везде, независимо от того, нужен ли это конкретный скрипт или нет, и отключить автокоммит - документация на php.net, если там очень плохо, ноAFAIR Я должен сделать это.Так что мой вопрос нет.1 и 2: Хорошо ли начинать транзакцию везде, независимо от того, нужен ли скрипт или нет?И должен ли я также отключить автокоммит?

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

~insert and/or update things
~do something aka "line 2"
~insert and/or update things again 

Похоже на пример, взятый прямо из книги.Я, очевидно, хочу, чтобы все вставки и обновления или ничего не произошло.Поскольку я уже начал транзакцию, я предполагаю, что ничего не будет зафиксировано, если только я не вызову mysqli_commit ($link);.Но здесь у нас есть небольшая проблема: я не включаю нижний колонтитул в конец своих сценариев, и теперь это кажется кошмаром, поэтому у меня нет места для размещения коммита.Так что вопроса нет.3: Будут ли мои запросы автоматически фиксироваться после завершения сценария (или я вызываю exit; или die();), даже если для autocommit задано значение false?Или мне нужно вызвать / не отключить автокоммит?

Теперь настало время для случая, когда что-то не получается и мне нужно откатиться.То же, что и выше - нужно ли мне вызывать mysqli_rollback (mysqli $link);, или достаточно того факта, что я не вызывал commit? Я ссылаюсь здесь на ситуацию, когда скрипт обычно не заканчивается.Ситуации, такие как отключение сервера во время работы на «линии 2» или остановка, потому что это заняло много времени (set_time_limit остановило его).

1 Ответ

0 голосов
/ 31 января 2019

Это довольно широкий вопрос, поэтому я постараюсь охватить все, что смогу.

Сначала вы можете игнорировать mysqli api (специфичные для api функции транзакций - это просто оболочки)и перейдите прямо к руководству MySQL .Здесь важно то, что отключение автоматической фиксации и запуск транзакции - это одно и то же.Также один запрос (включая модификации триггерами) всегда является транзакцией.

Ответ на ваш вопрос 1 и 2 «вероятно, нет».Это очень сильно зависит от того, что ваш существующий код предполагает относительно подключения к базе данных, и от того, как структурировано ваше приложение.

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

Для вопроса 3: он не будет фиксироваться автоматически,Однако вы можете сделать это, используя register_shutdown_function , хотя я не рекомендую это делать.

Существуют операторы ( неявные коммиты ), которые будут фиксироватьтранзакция автоматически.К ним относятся все операторы DDL (CREATE, ALTER ...), а также TRUCNATE, LOCK TABLES и другие.В основном это означает, что эти операторы не могут использоваться в транзакциях.

MySQL откатывает транзакции, когда соединение разрывается.

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

Классический подход:

START TRANSACTION
query
other things
another query
some other stuff
3-rd query
...
COMMIT

Главное здесь - убедиться, что вы делаете коммит, только если ошибок не было.

Оставьте откат до завершения соединения (или register_shutdown_function, если вы используете постоянные соединения), потому что убедиться, что каждый скрипт имеет корректно работающую логику отката, сложно:)

Это гарантирует, что ничего не будет совершено, если произойдут плохие вещи (исключения, фатальные ошибки, ограничения времени / памяти, перебои в подаче электроэнергии, метеоры ...).

Также возможно иметь транзакции в функции / методеуровень (вложенный и подобный стеку), но это выходит за рамки этого вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...