Python MySqlDB не получает обновленную строку
У меня есть script, который ждет, пока не будет обновлена какая-либо строка в db:
con = MySQLdb.connect(server, user, pwd, db)
Когда script начинает значение строки "running"
, и ожидает, что значение станет "finished"
while(True):
sql = '''select value from table where some_condition'''
cur = self.getCursor()
cur.execute(sql)
r = cur.fetchone()
cur.close()
res = r['value']
if res == 'finished':
break
print res
time.sleep(5)
Когда я запускаю этот script, он вешает навсегда. Хотя я вижу, что значение строки изменилось на "finished"
, когда я запрашиваю таблицу, распечатка script по-прежнему "running"
.
Есть ли какая-то настройка, которую я не установил?
EDIT: python script запрашивает только таблицу. Обновление к таблице выполняется с помощью приложения tomcat webapp с использованием JDBC, который установлен на автосообщении.
Ответы
Ответ 1
Это таблица InnoDB, не так ли? InnoDB - механизм транзакционного хранения. Установка autocommit в true, вероятно, поможет вам в этом.
conn.autocommit(True)
В качестве альтернативы вы можете изменить уровень изоляции транзакций. Вы можете узнать об этом подробнее:
http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
Причиной такого поведения является то, что внутри одной транзакции чтение должно быть последовательным. Все согласованные чтения в рамках одной транзакции считывают моментальный снимок, установленный первым чтением. Даже если вы script читаете только таблицу, это тоже считается транзакцией. Это поведение по умолчанию в InnoDB, и вам нужно изменить это или запустить conn.commit() после каждого чтения.
Эта страница объясняет это более подробно: http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html
Ответ 2
Я работал над этим, запустив
c.execute("""set session transaction isolation level READ COMMITTED""")
в начале сеанса чтения. Обновления из других потоков теперь проходят.
В моем примере я долгое время открывал связи (внутри mod_python), поэтому обновления других процессов вообще не просматривались.