Я уверен, что у этого есть простое решение, но я пока не смог его найти. При условии, баз данных InnoDB MySQL с уровнем изоляции, установленным в SERIALIZABLE и дали следующую операцию:Во время транзакции, как можно прочитать прочитанную строку до тех пор, пока транзакция не будет выполнена?
BEGIN WORK;
SELECT * FROM users WHERE userID=1;
UPDATE users SET credits=100 WHERE userID=1;
COMMIT;
Я хотел бы, чтобы убедиться, что как только выбор внутри транзакции выдаются, строка, соответствующий идентификатор пользователя = 1 заблокирован для читает, пока транзакция не будет выполнена. В настоящий момент UPDATE в этой строке будут ждать завершения транзакции, если она находится в процессе, но SELECT просто прочитает предыдущее значение. Я понимаю, что это ожидаемое поведение в этом случае, но мне интересно, есть ли способ заблокировать строку таким образом, чтобы SELECTs также дождались завершения транзакции для возврата значений?
Причина, по которой я ищу, заключается в том, что в какой-то момент и с достаточным количеством одновременных пользователей может случиться так, что в то время как предыдущая транзакция выполняется, кто-то еще читает «кредиты» для вычисления чего-то еще. В идеале код, выполняемый этим, должен ждать завершения транзакции для использования нового значения, поскольку в противном случае это может привести к необратимым проблемам с десинхронизацией.
Обратите внимание, что я не хочу блокировать всю таблицу для чтения, только определенную строку.
Кроме того, я мог бы добавить логическое «заблокированное» поле в таблицы и установить его в 1 каждый раз, когда начинаю транзакцию, но я действительно не чувствую, что это самое элегантное решение здесь, если нет абсолютно нет другого способа справиться с этим через mysql напрямую.
Вы можете поместить снимок таблицы во временную таблицу: 'CREATE TEMPORARY TABLE t_users SELECT * FROM users;'. – eggyal
Это не помогло бы, я хочу убедиться, что при выполнении транзакции чтение определенной строки будет отклонено, создание временной таблицы поможет только в том случае, если я должен удалить строку из основной таблицы и снова вставить ее обратно после того, как я закончил, но это звучит как слишком много поездок в БД. – Mahn
Плохо, я неправильно понял ваш вопрос. – eggyal