Problema Blocco Tabelle

di il
4 risposte

Problema Blocco Tabelle

Salve, volevo esporre il mio problema riguardo a una applicazione che blocca consecutivamente alcune tabelle in lettura/scrittura ; Il codice Sql che uso per bloccare è il seguente :

SET LOCK_TIMEOUT 1
SELECT...
FROM.....
WITH (UPDLOCK)
WHERE....

Le stored procedure sono tutte uguali ma vanno ad agire su tabelle diverse che non hanno relazioni tra loro , le transazioni sono diverse uno dall'altra così come le connessioni , L'errore che mi genera in .net è il 1222
, cioè Timeout della richiesta di blocco. Potrebbe essere un Bug ?

4 Risposte

  • Re: Problema Blocco Tabelle

    Ho scoperto che il problema è nella transazione che gli associo , se
    uso IsolationLevel.Serializable mi dà problemi , mentre se uso
    IsolationLevel.RepeatableRead funziona correttamente.... Forse non ho
    comunque spiegato bene il problema ; Ho 3 tabelle da bloccare che
    blocco in 3 momenti diversi con 3 transazioni diverse (ma che usano lo
    stesso tipo di isolamento) e con 3 SP diverse (SELECT * From .... With
    (UPDLOCK) WHERE .....). Dopo che ho lanciato la prima stored procedure
    (che va a buon fine) la seconda finchè non viene lanciata la tabella
    non è bloccata ma quando la vado a lanciare sembra quasi che si
    blocchi da sola e poi si veda bloccata da qualcun altro.... ??
  • Re: Problema Blocco Tabelle

    Se usi il livello IsolationLevel.Serializable puoi eseguire una transazione alla volta. non usare il lock sql con serializzable altrimenti rischi di finire in pericolosi deadlock.

    ti consiglio di non mettere lock e di usare il livello IsolationLevel.Serializable rileggendo da ogni client concorrente i dati prima di fare eventuali update.

    Ciao, Andrea

    mailto:
  • Re: Problema Blocco Tabelle

    Ciao, grazie per la risposta, ho ancora qualche dubbio in questione :
    Quando dici di non mettere il lock ti riferisci al LOCK_TIMEOUT
    oppure al WITH UPDLOCK ? SE è quest'ultimo il caso come faccio poi a bloccarle senza il blocco ? ciao
  • Re: Problema Blocco Tabelle

    Effettivamente sono stato un po' rapido nella risposta.

    Diciamo che se in linea di massima hai un problema di concorrenze, ti conviene usare gli strumenti che mamma Microsoft ti mette a disposizione in ADO.Net ovvero il DataSet e l'SQLDataAdapter. In quel caso, Apri una SqlTransaction Serializzata (puoi usare anche una connessione differente per ogni transazione non cambia niente gestisce tutto SQL Server) e fai il fill di un dataset framite il tuo oggetto SqlDataAdapter. A questo punto il livello di isolamento impostato non ti permette di eseguire alcunchè a livello di database sui dati che hai letto nel Dataset fin tanto che la transazione non viene chiusa tramite commit o rollback(Quindi attento ad usare la Serializable). In questo caso l'UPDLOCK è chiaramente inutile, le altre transazioni in ingresso verranno accodate.

    Se invece vuoi bloccare a mano una tabella, allora non usare il livello di Isolamento Serializable ma usa correttamente l'istruzione UPDLOCK con il livello di isolamento Chaos o meglio ancora Unspecified, ma stai molto attento a bloccare solo quello che ti serve, altrimenti rischi di bloccare tutto o fare degradare le prestazioni di accesso ai dati dell'applicazione.
    Se i blocchi che imposti sono troppo blandi puoi invece incappare in letture fantasma.

    Ricapitolando, se imposti un livello di isolamento per la transazione, i LOCK vengono automaticamente gestiti da ADO in funzione del livello di isolamento stesso:

    Chaos: Le modifiche in sospeso dalle transazioni più isolate non possono essere sovrascritte.

    ReadCommitted: La condivisione dei blocchi viene mantenuta durante la lettura dei dati per evitare letture "dirty", anche se è possibile modificare i dati prima del termine della transazione, con conseguente produzione di letture non ripetibili o dati fantasma.

    ReadUncommitted: È possibile una lettura "dirty", ovvero non verrà emesso alcun blocco condiviso, né verrà rispettato alcun blocco esclusivo.

    RepeatableRead :I blocchi vengono posizionati su tutti i dati utilizzati in una query, per impedire ad altri utenti di aggiornare i dati. Vengono impedite le letture non ripetibili, ma possono essere presenti righe fantasma.

    Serializable

    Viene posizionato un blocco di intervallo sull'oggetto DataSet, per impedire ad altri utenti di aggiornare o immettere righe nel dataset fino al termine della transazione.

    Unspecified: Verrà utilizzato un livello di isolamento diverso da quello specificato, ma il livello non potrà essere determinato.

    Spero di essere satao un po' più di aiuto rispetto al precedente post.

    Ciao, Andrea
Devi accedere o registrarti per scrivere nel forum
4 risposte