2009-10-24 11 views
11

Mam skrypt, który czeka, aż jakiś wiersz w db jest aktualizowana:Pythona MySQLdb nie zaczyna aktualizacja wiersz

con = MySQLdb.connect(server, user, pwd, db) 

Gdy skrypt rozpoczyna wartość wiersza jest "running" i czeka na wartość stać "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) 

Po uruchomieniu tego skryptu zawiesza się na zawsze. Mimo że widzę, że wartość wiersza zmieniła się na "finished", gdy zapytam o tabelę, wydruk skryptu nadal jest "running".

Czy jest jakieś ustawienie, którego nie ustawiłem?

EDYCJA: Skrypt Pythona odpytuje tylko tabelę. Aktualizacja do tabeli jest przeprowadzana przez webcat tomcat, używając JDBC, który jest ustawiony na autocommit.

Odpowiedz

17

To jest tabela InnoDB, prawda? InnoDB jest mechanizmem przechowywania transakcji. Ustawienie autocommit na true prawdopodobnie naprawi to zachowanie.

conn.autocommit(True) 

Alternatywnie można zmienić poziom izolacji transakcji. Więcej informacji na ten temat można znaleźć tutaj: http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html

Powodem tego zachowania jest to, że w pojedynczej transakcji odczyty muszą być spójne. Wszystkie spójne odczyty w ramach tej samej transakcji odczytują migawkę ustaloną przez pierwszy odczyt. Nawet jeśli skrypt czyta tylko tabelę, jest to również traktowane jako transakcja. Jest to domyślne zachowanie w InnoDB i musisz to zmienić lub uruchomić conn.commit() po każdym przeczytaniu.

Ta strona wyjaśnia to dokładniej: http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html

+0

To jest InnoDB. Ale skrypt Pythona odpytuje tylko tabelę. Aktualizacja do tabeli jest przeprowadzana przez webcat tomcat, używając JDBC, który * jest * ustawiony na autocommit. – olamundo

+0

Dodałem więcej szczegółów, aby wyjaśnić zachowanie –

3

Pracowałem wokół to uruchamiając

c.execute("""set session transaction isolation level READ COMMITTED""") 

wcześnie w moim sesji czytania. Aktualizacje z innych wątków przychodzą teraz.

W moim przykładzie utrzymywałem połączenia otwarte przez długi czas (wewnątrz mod_python) i dlatego aktualizacje innych procesów nie były w ogóle widoczne.