2013-08-13 13 views
7

Uso il modulo python sqlite3 per scrivere i risultati dei lavori batch su un file comune .db. Ho scelto SQLite perché più processi potrebbero provare a scrivere allo stesso tempo e, a quanto ho capito, SQLite dovrebbe gestirlo bene. Quello di cui non sono sicuro è cosa succede quando si concludono più processi e si tenta di scrivere contemporaneamente. Quindi, se più processi che assomigliano a questoScrittura simultanea con sqlite3

conn = connect('test.db') 

with conn: 
    for v in xrange(10): 
     tup = (str(v), v) 
     conn.execute("insert into sometable values (?,?)", tup) 

eseguire in una sola volta, faranno un'eccezione? Aspetta educatamente che gli altri processi scrivano? C'è un modo migliore per farlo?

+1

Non sono sicuro se si tratta di un dup: sto chiedendo il comportamento di un modulo Python specifico, non di SQLite in generale. – Shep

risposta

16

La libreria sqlite bloccherà il database per processo durante la scrittura nel database e ciascun processo attenderà il rilascio del blocco per il proprio turno.

Il database non deve essere scritto fino a commit tempo tuttavia. Stai utilizzando la connessione come gestore di contesto (buono!), Quindi il commit viene eseguito una volta completato il ciclo e tutte le istruzioni insert sono state eseguite.

Se il database presenta vincoli di univocità, è possibile che il commit non riesca perché un processo ha già aggiunto righe a cui un altro processo è in conflitto.

+1

quindi il blocco è abilitato a 'connect' o quando si verifica il commit? – Shep

+1

Il blocco viene afferrato durante la scrittura. –

+1

@MartijnPieters ... e il blocco viene rilasciato al ritorno dalla chiamata della funzione di commit. O mi sbaglio? –

4

Se ogni processo mantiene la propria connessione di quanto dovrebbe essere soddisfacente. Quello che succederà è che quando si scrive il processo si bloccherà il DB, così tutti gli altri processi si bloccheranno. Lanciano un'eccezione se viene superato il timeout per attendere che il DB sia libero. Il timeout può essere configurato attraverso la chiamata di connessione:

http://docs.python.org/2/library/sqlite3.html#sqlite3.connect

Non si consiglia di avere il file di DB in una condivisione di rete.

Aggiornamento:

Si consiglia inoltre di controllare il livello di isolamento: http://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.isolation_level

0

La buona notizia è quella biblioteca SqlLite utilizza implicitamente una transazione che blocca un database ogni volta che l'esecuzione di un LMD. Ciò significa che altri accessi concorrenti al database attenderanno fino al completamento della richiesta DML in esecuzione mediante il commit/rollback di una transazione. Si noti tuttavia che più processi possono eseguire SELECT allo stesso tempo.

Inoltre, fare riferimento allo Python SQL Lite 3.0 module nella sezione 11.13.6 - Controllo delle transazioni che descrive in dettaglio come le transazioni possono essere controllate.