2009-10-24 17 views
11

Ho uno script che attende fino a qualche riga in un db viene aggiornato:Python non sempre aggiornato fila

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

all'avvio dello script il valore della fila è "running", e attende per il valore di diventare "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) 

Quando eseguo questo script si blocca per sempre. Anche se vedo che il valore della riga è stato modificato in "finished" quando interrogo la tabella, la stampa dello script è ancora "running".

C'è qualche impostazione che non ho impostato?

MODIFICA: lo script python interroga solo la tabella. L'aggiornamento alla tabella viene eseguito da una webapp tomcat, utilizzando JDBC, impostata su autocommit.

risposta

17

Questa è una tabella InnoDB, giusto? InnoDB è un motore di archiviazione transazionale. L'impostazione di autocommit su true probabilmente risolverà questo comportamento per te.

conn.autocommit(True) 

In alternativa, è possibile modificare il livello di isolamento della transazione. Puoi leggere ulteriori informazioni al riguardo qui: http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html

Il motivo di questo comportamento è che all'interno di una singola transazione le letture devono essere coerenti. Tutte le letture coerenti all'interno della stessa transazione leggono l'istantanea stabilita dalla prima lettura. Anche se lo script legge solo la tabella, anche questa viene considerata una transazione. Questo è il comportamento predefinito in InnoDB e devi cambiarlo o eseguire conn.commit() dopo ogni lettura.

Questa pagina spiega questo in ulteriori dettagli: http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html

+0

È un InnoDB. Ma lo script python interroga solo la tabella. L'aggiornamento alla tabella viene eseguito da una webapp tomcat, utilizzando JDBC, che * è * impostato su autocommit. – olamundo

+0

Ho aggiunto ulteriori dettagli per spiegare il comportamento –

3

ho lavorato intorno a questo eseguendo

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

presto nella mia sessione di lettura. Gli aggiornamenti da altri thread vengono ora.

Nella mia istanza mantenevo aperte le connessioni per un lungo periodo di tempo (all'interno di mod_python) e quindi gli aggiornamenti di altri processi non venivano visti affatto.