2010-10-15 8 views
5

Ho una situazione come questa.Quale livello di isolamento utilizzare per impedire la lettura dei dati?

Query è simile a questo.

Select * from TABLE where ID = 1 

(quello che una query :)

dopo che posso cambiare roba in quella riga e inserirlo con il nuovo id.

Voglio impedire ad altre query di leggere quella prima riga originale da query, fino a quando non ho finito di leggere e inserire. Dopo ... vai avanti.

Fondamentalmente voglio selezionare e inserire per essere in transazione, con livello di isolamento che impedirà la lettura solo da quella riga fino al termine dell'inserimento.

OleDbTransaction è in gioco, perché io uso di SQL Server 6.5 (oh sì avete letto bene, non chiedere perché :)

stavo scavando attraverso la descrizione livelli di isolamento, ma non riesco a capirli e trovare soluzione per il mio problema, quindi la mia domanda è quale livello di isolamento usare per OleDbTransaction?

Spero di essere stato chiaro :)

Grazie.

risposta

-1

È necessario mettere un blocco sulla riga: creare il blocco prima di leggere la riga e rilasciare il blocco dopo aver aggiornato la riga.

In Oracle e banche dati simili, legge non bloccare, quindi è necessario eseguire le seguenti operazioni (in una transazione):

SELECT * FROM table WHERE id=? FOR UPDATE 
... 
UPDATE table .... 

In MS SQL, io non sono davvero sicuro, il modo più semplice sarebbe provare quanto segue: Aprire due finestre collegate al database, avviare una transazione in entrambi, fare SELECT e vedere se è possibile effettuare la selezione dal secondo. Se la dichiarazione non ritorna, significa che la riga è bloccata e tu sei bravo.

presumo, nella sua interrogazione, si significa per aggiornamento la fila dopo aver selezionato, non inserire situazione (inserimento crea una nuova riga, aggiornamento modifica una riga esistente)

+0

risposta inutile, perché il livello di isolamento di base in MS SQL è più lento di quello in Oracle – Andrey

+0

-1 Perché hai risposto per Oracle quando è SQL Server, quindi menzioni che non lo fai saperlo o? – gbn

+0

In primo luogo, qualcuno su Internet potrebbe imbattersi in questa pagina e utilizzare Oracle così ho pensato che potrei anche includerlo; in secondo luogo potrebbe essere simile in SQL Server, quindi potrebbe essere un puntatore nella giusta direzione. –

0

Descritto si chiama Phantom Read. Quindi è necessario l'isolamento serializzabile (SERIALIZABLE)

+0

perché questo è stato downvoted? – Andrey

+0

Per prima cosa ho messo questo livello di isolamento, e poi pochi altri, ma in ogni caso ho avuto errori nel dire che il processo che esegue la stessa query di selezione viene catturato in un deadlock e diventa vittima di deadlock e cancellato. Sembra che questa cosa con livelli di isolamento non sia la mia soluzione o sto facendo qualcosa di sbagliato .. – 100r

5

È necessario tenere il blocco della durata di una transazione. E anche esclusivamente.

Ora, non sono sicuro delle opzioni corrette per SQL Server 6.5. Non hanno lavorato con lui dal momento che, ehm, 199x

BEGIN TRAN 

--edit, changed to XLOCK, ROWLOCK, HOLDLOCK 
SELECT * from TABLE WITH (XLOCK, ROWLOCK, HOLDLOCK) where ID = 1 
... 
INSERT 

COMMIT 

Edit:

mio cambiamento mira a bloccare la singola riga esclusivamente (con granularità fine) alla fine del transazione.

Tuttavia, IIRC ROWLOCK è stato aggiunto con SQL Server 7 e 6.5 erano solo blocchi di pagina. Ma è passato un po 'di tempo. Avevo i capelli e i denti allora :-)

+0

non devo usare il blocco del tavolo. perché ci sono alcuni queris davvero pesanti in corso tutto il tempo, e TABLOCKX è il blocco del tavolo giusto? – 100r

+0

Vedere aggiornamento – gbn

+0

tnx. Non potevo far funzionare nessuno dei lucchetti. la query non verrà compilata. forse la sintassi di 6.5 è diversa. Ci proverò lunedì al lavoro, grazie a dio non ho 6,5 a casa :) – 100r

Problemi correlati