Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lock del record - proprio non lo capisco

88 views
Skip to first unread message

LittleWave

unread,
Nov 18, 2009, 3:19:17 AM11/18/09
to
Mi capita spesso il seguente problema:

1) Ho una form con una griglia che carico con con un recordset cosi'
impostato:
- CursorLocation = adUseClient
- CursorType = adOpenForwardOnly
- LockType = adLockReadOnly
la query viene eseguita su una vista

2) Con il doppio click su un elemento della griglia seleziono in modo
esclusivo quel record impostando il recordset in questo modo:
- CursorLocation = adUseServer
- CursorType = adOpenKeyset
- LockType = adLockPessimistic
avvio la transizione .BeginTrans
la query viene eseguita sulla tabella "fisica", non sulla vista

Una volta eseguita la query all'operatore viene visualizzata una form
dove puo' modificare i valori definiti dall'applicazione.

A questo punto se da un altro PC, si cerca di richiamare la form al
punto 1 (la griglia) si riceve il seguente messaggio:
Timeout della richiesta di blocco. Numero -2147217871

Mi domando e chiedo, sperando una volta per tutte di capirne il
funzionamento, ma come gestisce il lock del record SQL.

Grazie e ciao,
LittleWave


Zulu

unread,
Nov 18, 2009, 4:06:37 AM11/18/09
to
"LittleWave" ha scritto nel messaggio
news:f63d92a6-e5e7-4a2a...@w19g2000yqk.googlegroups.com...

>
> Mi domando e chiedo, sperando una volta per tutte di capirne il
> funzionamento, ma come gestisce il lock del record SQL.
>

Hai lockato in modo pessimistico un record e quindi il record ha un lock
esclusivo per tutta la durata delle operazioni di edit (anche ore se
l'operatore se ne va in giro lasciando la maschera aperta...).
Mi pare naturale che se da un'altra connessione (un altro PC nel tuo caso)
cerchi di recuperare anche quel record, la query (che sia una vista o acceda
direttamente alla tabella non fa nessuno differenza) si blocchi fin tanto
che l'operatore di cui sopra non si � deciso di concludere le operazioni di
edit.
Ma a te che serve fare, e che versione di SQL Server stai usando?

LittleWave

unread,
Nov 18, 2009, 5:28:03 AM11/18/09
to
On 18 Nov, 10:06, "Zulu" <du...@aol.com> wrote:
> "LittleWave"  ha scritto nel messaggionews:f63d92a6-e5e7-4a2a...@w19g2000yqk.googlegroups.com...

>
>
>
> > Mi domando e chiedo, sperando una volta per tutte di capirne il
> > funzionamento, ma come gestisce il lock del record SQL.
>
> Hai lockato in modo pessimistico un record e quindi il record ha un lock
> esclusivo per tutta la durata delle operazioni di edit (anche ore se
> l'operatore se ne va in giro lasciando la maschera aperta...).

E' proprio quello che capita spesso........

> Mi pare naturale che se da un'altra connessione (un altro PC nel tuo caso)
> cerchi di recuperare anche quel record, la query (che sia una vista o acceda
> direttamente alla tabella non fa nessuno differenza) si blocchi fin tanto

> che l'operatore di cui sopra non si è deciso di concludere le operazioni di
> edit.

Quando mi scrivi "Mi pare naturale che se da un'altra......." mi
chiedo perche' naturale?
Se sto accedendo a quel "record" in SOLA lettura perche' non ci fai
accedere?

> Ma a te che serve fare

Vorrei accedere, in lettura, anche a quei records che sono in lock.

>, e che versione di SQL Server stai usando?

La versione di SQL Server e' la 2005 SP2.

Grazie per la risposta, ciao,
LittleWave

Zulu

unread,
Nov 18, 2009, 6:00:31 AM11/18/09
to
"LittleWave" ha scritto nel messaggio
news:d4511210-40a2-494b...@v25g2000yqk.googlegroups.com...

> Quando mi scrivi "Mi pare naturale che se da un'altra......." mi
> chiedo perche' naturale?
> Se sto accedendo a quel "record" in SOLA lettura perche' non ci fai
> accedere?
>

Il livello di isolamento di default (read commited, vedi:
http://msdn.microsoft.com/it-it/library/ms173763(SQL.90).aspx
anche se in italiano non � che sia proprio chiaro...
) non permette di leggere dati che sono ancora sotto transazione.

> Vorrei accedere, in lettura, anche a quei records che sono in lock.

> La versione di SQL Server e' la 2005 SP2.
>

Hai due strade, o nella query che ti estrae i dati per la sola
visualizzazione usi l'hint nolock per "fregartene" dei lock piazzati da
altre connessioni che stanno bloccando le righe dove � in corso l'editing:

select * from tuaQuery with (nolock) where ...
(vedi http://msdn.microsoft.com/it-it/library/ms187373(SQL.90).aspx)

Ma in questo modo la tua query pu� recuperare dati che sono ancora in fase
di aggiornamento (per esempio, se qualcuno su una riga che � sotto
transazione ti ha aggiornato solo il cognome e non ancora il nome, la tua
query ti restituir� quella riga con il cognome nuovo e il nome vecchio).

Oppure un'altra soluzione, credo pi� robusta, che puoi adottare visto che
usi SQL 2005, � quella di impostare l'opzione READ_COMMITTED_SNAPSHOT a ON
sul tuo database e *NON* usare l'hint nolock nella query.
In questo modo l'accesso in lettura ad una riga che � ancora in fase di
aggiornamento recuperer� la versione precedente della stessa riga, cio� le
versione "vecchia" che sta subendo le modifiche. Nell'esempio di prima, la
tua query ti restituir� il cognome e il nome vecchi, e non il "misto mare"
causato dall'uso dell'hint nolock.
Nel primo link che ti ho indicato trovi spiegato come funziona l'opzione
read_commited_snapshot un po' pi� in dettaglio.

dawn

unread,
Nov 18, 2009, 8:39:33 AM11/18/09
to
On 18 Nov, 09:19, LittleWave <o.spallanz...@tin.it> wrote:
> 1) Ho una form con una griglia che carico con con un recordset cosi'
> impostato:
>
> 2) Con il doppio click su un elemento della griglia seleziono in modo
> esclusivo quel record impostando il recordset in questo modo:
> - CursorLocation = adUseServer
> - CursorType = adOpenKeyset
> - LockType = adLockPessimistic

Tu qui stai chiedendo (i.e. adLockPessimistic) di bloccarlo a chiunque
(+ o -)... non puoi lamentartene poi!!!
E comunque è sbagliato; devi:
1) portarlo sul form con una select di sola lettura id est *NON*
loccato
2) attendere che l'Utente si faccia i suoi porci comodi
3) alla conferma controllare che il record sia rimasto lo stesso
4) se il 3 è verificato aggiornare le informazioni

La differenza con il tuo, sostanziale, è che si locca dopo, per i
nanotempo che serve all'aggironamento

LittleWave

unread,
Nov 18, 2009, 8:55:46 AM11/18/09
to
On 18 Nov, 12:00, "Zulu" <du...@aol.com> wrote:
> "LittleWave"  ha scritto nel messaggionews:d4511210-40a2-494b...@v25g2000yqk.googlegroups.com...

>
> > Quando mi scrivi "Mi pare naturale che se da un'altra......." mi
> > chiedo perche' naturale?
> > Se sto accedendo a quel "record" in SOLA lettura perche' non ci fai
> > accedere?
>
> Il livello di isolamento di default (read commited, vedi:http://msdn.microsoft.com/it-it/library/ms173763(SQL.90).aspx
> anche se in italiano non è che sia proprio chiaro...

> ) non permette di leggere dati che sono ancora sotto transazione.
>
> > Vorrei accedere, in lettura, anche a quei records che sono in lock.
> > La versione di SQL Server e' la 2005 SP2.
>
> Hai due strade, o nella query che ti estrae i dati per la sola
> visualizzazione usi l'hint nolock per "fregartene" dei lock piazzati da
> altre connessioni che stanno bloccando le righe dove è in corso l'editing:

>
> select * from tuaQuery with (nolock) where ...
> (vedihttp://msdn.microsoft.com/it-it/library/ms187373(SQL.90).aspx)
>
> Ma in questo modo la tua query può recuperare dati che sono ancora in fase
> di aggiornamento (per esempio, se qualcuno su una riga che è sotto

> transazione ti ha aggiornato solo il cognome e non ancora il nome, la tua
> query ti restituirà quella riga con il cognome nuovo e il nome vecchio).
>
> Oppure un'altra soluzione, credo più robusta, che puoi adottare visto che
> usi SQL 2005, è quella di impostare l'opzione READ_COMMITTED_SNAPSHOT a ON

> sul tuo database e *NON* usare l'hint nolock nella query.
> In questo modo l'accesso in lettura ad una riga che è ancora in fase di
> aggiornamento recupererà la versione precedente della stessa riga, cioè le

> versione "vecchia" che sta subendo le modifiche. Nell'esempio di prima, la
> tua query ti restituirà il cognome e il nome vecchi, e non il "misto mare"

> causato dall'uso dell'hint nolock.
> Nel primo link che ti ho indicato trovi spiegato come funziona l'opzione
> read_commited_snapshot un po' più in dettaglio.

Grazie della esaustiva risposta, ho provato, su un DB di test, la
seconda soluzione che mi hai proposto e sembra funzionare
correttamente, perlomeno non sono piu' riuscito a replicare l'anomalia
segnalata in precedenza.

Grazie di nuovo, ciao,
LittleWave

LittleWave

unread,
Nov 18, 2009, 9:02:55 AM11/18/09
to

Hai perfettamente ragione, avevo pensato anche a questa soluzione ma
sono rimasto sull'altra (soluzione) per la difficolta' (scrivere
dell'altro codice :-).....) di controllare che il record sia rimasto
lo stesso, il punto 3 che mi hai segnalato.

In ogni caso la soluzione potrebbe essere poco gradita all'utente
finale, in quanto una volta che ha apportato le modifiche ai campi
presenti nella form, che potrebbero anche essere tanti e complessi,
potrebbe poi essere costretto a reinserirli in quanto un altro utente
nel frattempo ha modificato anche un solo valore sullo stesso record.

Grazie, ciao,
LittleWave

0 new messages