Possiedo un database Oracle a cui accedo utilizzando Devart e Entity Framework.Lettura e aggiornamento simultanei in una tabella di database
C'è un tavolo chiamato IMPORTJOBS
con una colonna STATUS
.
Ho anche più processi in esecuzione allo stesso tempo. Ognuno di loro legge la prima riga in IMPORTJOBS
che ha lo stato 'REGISTERED'
, lo mette nello stato 'EXECUTING'
e, se fatto, lo mette nello stato 'EXECUTED'
.
Ora, perché questi processi sono in esecuzione in parallelo, credo che la seguente potrebbe accadere:
- processo Una legge fila 10, che ha lo status di
REGISTERED
, - processo B si legge inoltre fila 10 che ha ancora lo status
REGISTERED
, - processo Una riga di aggiornamento 10 allo stato
EXECUTING
.
Il processo B non dovrebbe essere in grado di leggere la riga 10 mentre il processo A lo ha già letto e sta per aggiornarne lo stato.
Come dovrei risolvere? Metti letto e aggiorna in una transazione? O dovrei usare un approccio di versioning o qualcos'altro?
Grazie!
EDIT: grazie alla risposta accettata, l'ho ottenuto funzionante e l'ho documentato qui: http://ludwigstuyck.wordpress.com/2013/02/28/concurrent-reading-and-writing-in-an-oracle-database.
grazie, sto cercando di eseguire "SELECT * FROM IMPORTJOBS WHERE STATUSCODE = 'REGISTRATO' E ROWNUM <= 1 PER AGGIORNA SALTA BLOCCATO", ma sta ancora restituendo la stessa riga dai diversi processi? –
(1) assicurarsi di aver disattivato l'autocommit: non è possibile bloccare una riga senza una transazione. (2) 'FOR UPDATE SKIP LOCKED' e' rownum' [non funzionerà come previsto] (http://stackoverflow.com/questions/5847228/oracle-select-for-update-behaviour) - questo perché lo SKIP LOCKED viene valutato ** dopo ** la clausola WHERE. Usa una selezione senza rownum, recupera una (o più come necessario) riga e chiudi il cursore, questo è il modo migliore per usare SKIP LOCKED. –
infatti, ho dovuto mettere la selezione e l'aggiornamento in una transazione, ora funziona. Grazie!!! –