MariaDB. Использовать откат транзакции без блокировки таблиц - PullRequest
0 голосов
/ 01 июня 2019

На веб-сайте, когда пользователь публикует комментарий, я делаю несколько запросов, вставок и обновлений. (На MariaDB 10.1.29)

Я использую START TRANSACTION, поэтому, если какой-либо запрос не выполняется в любой заданной точке, я могу легко выполнить откат и удалить все изменения. Теперь я заметил, что это блокирует таблицы, когда я делаю INSERT из другого INSERT, и я не говорю во время выполнения запроса, это очевидно, но до транзакции не закрыто .

Тогда DELETE блокируется, только если они имеют общий индексный ключ (комментарии для той же страницы), но, к счастью, UPDATE не заблокирован.

Могу ли я выполнить любую транзакцию, которая не блокирует таблицу от новых вставок (пока транзакция выполняется, а не фактический запрос), или любой другой метод, который позволяет мне удобно "отменить" любой запрос, выполненный после некоторого момента?

PD:

Я запускаю транзакцию с функцией PHP mysqli_begin_transaction() без какой-либо из flags, а затем mysqli_commit().

Ответы [ 2 ]

1 голос
/ 02 июня 2019

Все операции записи работают аналогичным образом - они блокируют строки , к которым они касаются (или могут коснуться), с момента выполнения оператора до закрытия транзакции с помощью COMMIT или * 1004.*.SELECT...FOR UPDATE и SELECT...WITH SHARED LOCK также участвуют.

Когда происходит операция записи, выполняется проверка взаимоблокировки.

В некоторых ситуациях существует блокировка «пробела».* com_id оказался последним идентификатором в таблице?

Вы не указали SELECTs, что требовалось FOR UPDATE?

1 голос
/ 02 июня 2019

Я не думаю, что простой INSERT блокирует другие вставки дольше, чем время вставки. AUTO_INC блокировки не удерживаются в течение полного времени транзакции.

Но если две транзакции пытаются ОБНОВИТЬ одну и ту же строку, как в следующем выражении (два ответа на один и тот же комментарий)

UPDATE comment SET replies=replies+1 WHERE com_id = ?

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

Я думаю, все, что вы можете сделать, - это максимально сократить время транзакции.Например, вы можете подготовить все выписки до начала транзакции.Но это вопрос миллисекунд.Если вы передаете файлы, и это может занять 40 секунд, вам не следует делать это, пока транзакция базы данных открыта.Перед тем как начать транзакцию, передайте файлы и сохраните их с именем, указывающим, что операция не завершена.Вы также можете сохранить их в другой папке, но в том же разделе.Затем, когда вы запускаете транзакцию, вам просто нужно переименовать файлы, что не должно занять много времени.Время от времени вы можете очищать и удалять непереименованные файлы.

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