3 messaggi dal 28 dicembre 2011
buongiorno a tutti

in una pagina ASP classic
come posso bloccare un record di una tabella Access per impedire l'aggiornamento dello stesso record da un altro utente
ho provato con le seguenti istruzioni

sql_rev = "Select * from review where rv_az='" & w_az & "'" & "and rv_cod='" & request("rv_cod") & "'"

set rs_review = server.createobject("ADODB.recordset")
rs_review.CursorLocation = 2 '"adUseServer" pone il Lock sul server
rs_review.CursorType = 2 'adOpenDynamic
rs_review.LockType = 2 'adLockPessimistic
rs_review.Open sql_rev,con

a questo punto il record letto dovrebbe essere locked


Utente A
mostro i dati del record letto in una form
utente A modifica i dati ma non salva


Utente B
apro la stessa pagina e interrogo lo stesso record
non mi dà alcun avviso
utente B modifica i dati e salva la pagina
cosicchè quando l'utente A salva le sue modifiche
copre le modifiche dell'utente B

qual'e' il metodo per evitare questo problema ?

grazie Mauro
Modificato da falco4 il 26 luglio 2012 15.18 -
Modificato da falco4 il 26 luglio 2012 15.20 -
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao e benvenuto!

falco4 ha scritto:

a questo punto il record letto dovrebbe essere locked

sì, ma solo finché la connessione resta aperta. Immagino che tu la chiuda poche righe più in basso, e quindi il lock viene ben presto rilasciato.
Quello che stai facendo è corretto; non bisogna mai tenere aperta una connessione più del minimo tempo necessario a leggere o scrivere dati.

Devi attuare un'altra soluzione.
Potresti aggiungere un nuovo campo alla tabella review che puoi chiamare "Versione". Questo campo può essere di tipo DateTime, Uniqueidentifier oppure semplicemente un numero intero. Il valore contenuto in questo campo ti servirà quando andrai ad aggiornare i dati. Se, da quando il record era stato letto, il valore è rimasto lo stesso, allora l'UPDATE può avvenire, altrimenti no. Con l'UPDATE devi anche cambiare o incrementare questo valore, in modo che una UPDATE concorrente da parte di altri utenti fallisca dato che, nel frattempo, il valore per loro è cambiato.

Quindi, quando l'utente apre la maschera di modifica, devi depositare il valore di "Versione" in un campo hidden, così che verrà poi postato insieme a tutti gli altri dati. Tu lo leggi e vai a verificare se è nel database rimasto lo stesso o no (potresti anche usarlo nella clausola WHERE della UPDATE). Se è cambiato, informerai l'utente che nel frattempo qualcun altro ha modificato i dati e quindi gli chiederai conferma se intende proseguire lo stesso con l'aggiornamento (sovrascrivendo il lavoro dell'altro utente) o se invece vuole controllare quali sono i valori attuali.

Ovviamente puoi arricchire la tabella di altri campi (o creare una tabella separata). Ad esempio all'utente1 farà piacere sapere che "utente2 ha iniziato a modificare questo elemento 3 minuti fa". Quindi ti servono altri due campi che contengano username e data/ora di inizio della modifica. Così potrà decidere sin da subito se tornare più tardi o iniziare comunque la modifica.

Se vuoi proprio impedirgli di modificare i dati (ma non è una bella cosa impedire all'utente di lavorare), puoi controllare quella data/ora di inizio modifica e, se sono trascorsi meno di 20 minuti, mostrargli una pagina in sola lettura.

Ho scritto 20 minuti ma avrei dovuto dire "il tempo di durata della sessione". Se non facessi così, l'utente potrebbe acquisire il privilegio di modifica di un record per poi non rilasciarlo mai più se, per motivi suoi, dovesse chiudere il browser o dimenticarsi di "sbloccare" il record.

ciao

Enjoy learning and just keep making
3 messaggi dal 28 dicembre 2011
BrightSoul ha scritto:
ciao e benvenuto!

falco4 ha scritto:

a questo punto il record letto dovrebbe essere locked

sì, ma solo finché la connessione resta aperta. Immagino che tu la chiuda poche righe più in basso, e quindi il lock viene ben presto rilasciato.
Quello che stai facendo è corretto; non bisogna mai tenere aperta una connessione più del minimo tempo necessario a leggere o scrivere dati.

Devi attuare un'altra soluzione.
Potresti aggiungere un nuovo campo alla tabella review che puoi chiamare "Versione". Questo campo può essere di tipo DateTime, Uniqueidentifier oppure semplicemente un numero intero. Il valore contenuto in questo campo ti servirà quando andrai ad aggiornare i dati. Se, da quando il record era stato letto, il valore è rimasto lo stesso, allora l'UPDATE può avvenire, altrimenti no. Con l'UPDATE devi anche cambiare o incrementare questo valore, in modo che una UPDATE concorrente da parte di altri utenti fallisca dato che, nel frattempo, il valore per loro è cambiato.

Quindi, quando l'utente apre la maschera di modifica, devi depositare il valore di "Versione" in un campo hidden, così che verrà poi postato insieme a tutti gli altri dati. Tu lo leggi e vai a verificare se è nel database rimasto lo stesso o no (potresti anche usarlo nella clausola WHERE della UPDATE). Se è cambiato, informerai l'utente che nel frattempo qualcun altro ha modificato i dati e quindi gli chiederai conferma se intende proseguire lo stesso con l'aggiornamento (sovrascrivendo il lavoro dell'altro utente) o se invece vuole controllare quali sono i valori attuali.

Ovviamente puoi arricchire la tabella di altri campi (o creare una tabella separata). Ad esempio all'utente1 farà piacere sapere che "utente2 ha iniziato a modificare questo elemento 3 minuti fa". Quindi ti servono altri due campi che contengano username e data/ora di inizio della modifica. Così potrà decidere sin da subito se tornare più tardi o iniziare comunque la modifica.

Se vuoi proprio impedirgli di modificare i dati (ma non è una bella cosa impedire all'utente di lavorare), puoi controllare quella data/ora di inizio modifica e, se sono trascorsi meno di 20 minuti, mostrargli una pagina in sola lettura.

Ho scritto 20 minuti ma avrei dovuto dire "il tempo di durata della sessione". Se non facessi così, l'utente potrebbe acquisire il privilegio di modifica di un record per poi non rilasciarlo mai più se, per motivi suoi, dovesse chiudere il browser o dimenticarsi di "sbloccare" il record.

ciao
3 messaggi dal 28 dicembre 2011
BrightSoul
grazie per la risposta ma quando dico
"a questo punto il record letto dovrebbe essere locked" in realtà
a me non risulta affatto locked perchè se tento di accedere allo stesso
record da un altro terminale e faccio una modifica la stessa viene registrata con tanti saluti all'utente che già aveva "LOKKATO" il record per modifica.

volevo sapere se il procedimento che avevo usato per il lock del record era giusto oppure no.
Altrimenti come giustamente mi dici devo utilizzare un'altra soluzione
grazie
11.886 messaggi dal 09 febbraio 2002
Contributi
Ciao, come ti dicevo, il lock resta attivo solo mentre la connection è aperta. Cioè, quando invochi conn.Close, il lock viene rilasciato. Quindi tu stai acquisendo un lock che dura per un tempo brevissimo, una frazione di secondo.

Siccome non è una buona pratica quella di mantenere aperta una connessione, allora devi usare un altro sistema. Per esempio potresti valutare la soluzione col campo "versione" di cui ti parlavo nel post precedente.

ciao

Enjoy learning and just keep making

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.