Почему некоторые подключения mysql выбирают старые данные из базы данных mysql после удаления + вставки? - PullRequest
7 голосов
/ 17 февраля 2012

У меня проблема с сессиями в моем веб-приложении на python / wsgi.Для каждого потока в каждом из двух процессов демона wsgi существует разное постоянное соединение mysqldb.Иногда, после удаления старых сеансов и создания нового, некоторые соединения по-прежнему извлекают старые сеансы из выбора, что означает, что они не могут подтвердить сеанс и снова запросить вход в систему.

Подробности: сеансы хранятся вТаблица InnoDB в локальной базе данных MySQL.После аутентификации (через CAS) я удаляю все предыдущие сеансы для этого пользователя, создаю новый сеанс (вставляю строку), фиксирую транзакцию и перенаправляю на первоначально запрошенную страницу с новым идентификатором сеанса в файле cookie.Для каждого запроса идентификатор сеанса в файле cookie сравнивается с сеансами в базе данных.

Иногда вновь созданный сеанс не обнаруживается в базе данных после перенаправления.Вместо этого старый сеанс для этого пользователя все еще там.(Я проверил это, выбрав и зарегистрировав все сессии в начале каждого запроса).Почему-то я получаю кешированные результаты.Я попытался выбрать сеансы с помощью SQL_NO_CACHE, но это не имело никакого значения.

Почему я получаю кэшированные результаты?Где еще может происходить кеширование и как его остановить или обновить кеш?В основном, почему другие соединения не видят вновь вставленные данные?

Ответы [ 2 ]

12 голосов
/ 17 февраля 2012

MySQL по умолчанию имеет уровень изоляции «REPEATABLE READ», что означает, что вы не увидите изменений в вашей транзакции, которые были сделаны после ее запуска - даже если эти (другие) изменения были зафиксированы.

Если вы выполните команду COMMIT или ROLLBACK в этих сеансах, вы должны увидеть измененные данные (потому что это завершит транзакцию, которая «выполняется»).

Другой вариант - изменить уровень изоляции для этих сессий на «READ COMMITTED». Может быть, есть возможность изменить уровень по умолчанию, но вам нужно проверить руководство для этого.

2 голосов
/ 15 мая 2014

Да, похоже, предполагается, что вы собираетесь выполнить только одну транзакцию, а затем отключиться. Если у вас есть другая потребность, вам нужно обойти это предположение. Как уже упоминалось @a_horse_with_no_name, вы можете добавить коммит (хотя я бы использовал откат, если вы на самом деле не меняете данные). Или вы можете изменить уровень изоляции на курсоре - с это обсуждение Я использовал это:

dbcursor.execute("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED")

Или, похоже, вы можете установить автоматическую фиксацию в true для соединения:

dbconn.autocommit(True)

Хотя, опять же, это не рекомендуется, если вы действительно вносите изменения в соединение.

...