Newsgroup: it.comp.lang.visual-basic
Titolo: (Lungo) Bloccare un record

Ciao a tutti, mi trovo nella necessità di dover bloccare un record
mentre l'utente Pippo lo modifica in modo che tutti gli altri utenti
non vi possano apportare moficihe contemporaenamente,
altrimenti l'ultimo che salva il record ha la meglio.
VB6+DAO 3.51 permettono di bloccare più record alla volta
(a pagine di 2k). Cercando tra i vecchi posto con google ho
letto che con il DAO 3.6 si può bloccare anche un solo record,
solo che non c'è scritto come, ho meglio, fa riferimento al sito
comune (ancora quando era murialdo...), ma li non ho trovato
niente.
Avevo pensato di risolvere il problema aggiungendo un campo
al record, in cui l'utente che andava a modificare un record
scrivere il proprio Codice in modo che gli altri utenti non appena
cercavano di aprire quel record il programma li bloccava, solo
che ho il grosso problema che i tempi di reazione sono altrissimi!!!
Addirittura di qualke secondo
(( 
Nel senso che il client A scrive nel MDB sul disco di rete un valore 
e il client B continua a vedere il vecchio valore per almeno qualke 
secondo... con il rischio che gli utenti si ammazzino le modifiche 
l'un l'altro...
Grazie del possibile aiuto.
Pusky

 Addirittura di qualke secondo
a parte tutto il resto, questa lentezza da te segnalata potrebbe essere causata
dall'utilizzo dei controlli data o adodc per l'accesso ai dati, utilizzando direttamente
gli oggetti recordset ciň non avviene
Salutoni
Sergio


Invece è proprio con i recordset che ciò avviene.
Ho fatto qualche prova 'alla buona' con ADO, è in effetti i tempi
diventano biblici anche con due instanze del programma che girano
sul disco locale.
Hai mica altri suggerimenti... sono alla frutta!!!!
Saluti,
Pusky

 sul disco locale.
mi permetto di dubitare della tua affermazione.....
Prova a postare il codice che utilizzi.
Salutoni
Sergio

 altrimenti l'ultimo che salva il record ha la meglio.
A parte la lentezza (più di tanto non si può fare), leggi tutto il 3d
http://makeashorterlink.com/?F29052203

 Prova a postare il codice che utilizzi.
Ri grazie per le risposte.
Non sto a postarti il codice, ma credimi, se usassi un Data controll me
ne accorgerei ;-) si notano a video.
Per quanto riguarda adodc, nei References ho solo Microsoft DAO
3.6 Object Library.
Alla buona il mio codice fa così:
Sub LeggiScheda (beccati sto IDPassato)
Apro il Db
Apro il Recordset Where ID = IDPassato
Il campo Utente è vuoto
    -> SI -> EDIT scrivo il mio nome UPDATE e imposto un mio
    flag di accesso con possibilità di scrittura
    -> NO-> imposto un mio flag di accesso di sola lettura
Visualizza il record a video
Chiudo tutto.
Prima l'oggetto Database lo aprivo al caricamento della maschera
e lo chiudevo all'uscita. Lo stesso facevo con il recordset.
Poi sperando di ridurre il tempo di scrittura ho cominciato ad aprire
e chiudere il tutto ogni volta, pensavo che la chiusura lo costringesse
a buttare tutto quello che aveva in qualche sua cache direttamente
su disco.
Se il record viene scritto e letto dal computer locale, no problem, i
tempi sono molto ridotti (con DAO, non con ADO), comunque è
un caso inutile... se invece il tutto avviene su rete, i tempi sono
più alti.
Non so se serve dirlo, ma la rete è composta da una 30 di PC,
collegati a 2 switch 100 Mbit. Server doppio processore con
dischi SCSI. I client utilizzati per le prove sono un P2 350 e un
P4 1600.
Ancora grazie per l'interessamento.
Saluti,
Pusky


Grazie per la risposta Lupo, a dire la verità quel messaggio
non lo avevo trovato con google (colpa mia avevo cercato
la parola blocco e non lock...)
Comunque come logica penso sia simile alla mia. Tra
l'altro la mia idea è totalmente ispirata ad una serie di
messaggi comparsi sul NG verso luglio, solo che non
trovo neanche quelli con google... sono proprio sfigato.
Comunque ora provo a gestire una tabella separata per
i lock al posto di usare un campo della tabella dei dati,
magari così funziona meglio.
Farò sapere.
Grazie ancora,
Pusky

 su disco.
uhm.... cerchiamo di capire....(cerco di capire, of course, è che ormai ho il plurale
maiestatis incorporato)
Il problema della lentezza è relativo al tempo di esecuzione della routine che modifica il
dato sul db oppure ti risulta che dopo aver "aggiornato" il record (quindi terminata
l'esecuzione dello pseudo-codice da te postato) una eventuale interrogazione della tabella
riporta i dati vecchi?
Salutoni
Sergio


L'interrogazione della tabella riporta i dati vecchi.
La modifica del dato è una cosa 'immediata' a livello di esecuzione del
codice.
Solo ke il file risulta 'non aggiornato', se letto da un altro computer.
Saluti,
Pusky (siamo omonimi)


Ciao,
se non ho frainteso la tua risposta, suggerisci di utilizzare una tabella
in cui salvo i riferimenti (ID) dei record bloccati, e prima di bloccare
un record controllo che non sia bloccato da un altro utente.
Se non ho capito male, questo è quello che ho fatto, ma il risultato
non cambia.
Ti posto il codice che utilizzo per creare il record del blocco
Private Function xControllaLoginFE(ByRef IDPassato As Long) As Boolean
    '-----funzione che controlla se il record è bloccato, in caso contrario
lo blocco io
    Dim tbBlocco As Recordset
    Set tbBlocco = dbScadenze.OpenRecordset("SELECT tabBlocchi.* from
tabBlocchi where IDScadenza = " & CStr(IDPassato))
    If tbBlocco.RecordCount <> 0 Then
        '-----preso -> bloccato da...
        If tbBlocco("utente") = Connessione.Cognome & " " & Connessione.nome
Then
            '-----bloccato da me
            xControllaLoginFE = True
        Else
            '-----bloccato da altri
            xControllaLoginFE = False
        End If
    Else
        '-----lo blocco
        tbBlocco.AddNew
        tbBlocco("Utente") = Connessione.Cognome & " " & Connessione.nome
        tbBlocco("IDScadenza") = IDPassato
        tbBlocco.Update
        xControllaLoginFE = True
    End If
    tbBlocco.Close
End Function
Grazie,
Pusky

SUPER CUT
Ciao,
Ti posto la routine che utilizzo per creare il blocco del record (ora
il blocco del record lo scrivo su un'apposita tabella). Comunque anche
così la cosa non funziona, se non aspettando qualche secondo.

Saluti,
Pusky

 End Function


Se allora al posto di controllare che il blocco sia mio, faccio bloccare il
record da tutti e controllo che solo il primo ad averlo bloccato possa
modificarlo?
A naso direi che potrebbe funzionare.
Ora provo e poi ti faccio sapere.
Ancora grazie,
Pusky

[Lupo] ha scritto:
(snippone assoluto)
Il problema segnalato da pusky, al di lą delle logiche di implementazione del
blocco, mi sembra relativo ad un "ritardo" dell'aggiornamento del database...
Da quello che ho capito, la "mimica" dovrebbe essere questa:
un client aggiunge e/o modifica un record sul db condiviso
un altro client, interrogando immediatamente dopo la stessa tabella, "legge" i
dati come erano prima della modifica e/o inserimento.
Questo comportamento dovrebbe essere quello tipico degli oggetti adodc, che, da
quello che ho capito, si tengono in pancia per un certo tempo gli aggiornamenti,
ma agendo sul db senza la mediazione di questi oggetti la cosa non dovrebbe
verificarsi.
Dall'estratto di codice inviato viene utilizzato DAO, visto che mi pare di
ricordare che tu lo usi abbastanza spesso ;-), hai mai ricontrato un problema
del genere?
Dubbio: non č che per connettersi al database usa una fonte dati dsn? Io non
l'ho mai usata (tranne che nel codice vbscript), ma qualcuno sa dire se pone
questi problemi di ritardo?
Salutoni
Sergio

 del genere?
Assolutamente no. Però, attenzione, io non uso alcun oggetto databound, ma
solo codice, quindi non saprei dire se tali oggetti hanno o meno questo
problema.
Rammento solo che su un'installazione DAO 3.51 win2000 SP1 accadevano cose
strane: Scrivevi il record (con programmi esterni, VisData, verificavo che
ci fosse e c'era), ma l'altra postazione non lo vedeva. La cosa appariva
casuale. Ho montato SP2 e DAO 3.6  e il problema è scomparso. Purtroppo non
so dire (avendo fatto il tutto in una botta sola) se il "merito" fosse di
DAO 3.6 o di SP2 per win2000. Penso quest'ultimo in quanto il problema non
si presentava, pur con DAO 3.51, su altri sistemi operativi.

 si presentava, pur con DAO 3.51, su altri sistemi operativi.
Il mio sistema (quello su cui faccio prevalentemente le prove) è un Win2000,
ma non
ricordo a che SP sono (1 o 2... o liscio ;-) e gli stessi problemi si
verificano sia
con DAO 3.51 sia con DAO 3.6. Forse ho omesso di dire che il db è in ACCESS
97.
Se la soluzione fosse passare da DAO 3.51 a DAO 3.6, non ci sarebbero
problemi,
ma se la soluzione fosse installare il SP .... sarebbeun problema. Non tutti
i clienti
sono disposti a fare un gesto così avventato... Chi li regge poi se per caso
dopo
ci sono altri tipi di problemi. Comunque ho trovato una soluzione veramente
losca
che mi vergogno a dire, però funziona. Per ora la lascio nel cassetto come
piano
B, ora provo una gestione più seria.
Vi faccio sapere.
Saluti,
Pusky

 che mi vergogno a dire, però funziona.
Se il problema è di SO e/o di combinazione DAO/Jet con lo stesso, prima o
poi si ripresenta.
Vedi anche qui:
http://makeashorterlink.com/?P61425EA2
 (in particolare il link M$ citato fra
i vari interventi)

MEGA CUT
Conclusione della storia, ho risolto così (anche se devo spiegare
il tutto al responsabile ed aspettare la sua benedizione):
Quando l'untente A apre un record, in una tabella viene scritto il
suo nome e l'ID del record
Questo succede per tutti gli utenti che aprono record.
Quando un utente tenta di salvare il record, il programma
filtra la tabella dei blocchi per vedere quanti hanno aperto il
record con l'ID in questione. Se l'utente che sta salvando
il record è il primo della lista, ok, altrimenti dico che il record
è bloccato dall'utente primo nella lista. Finche l'utente che vuole
salvare il record non è il primo della lista (quindi gli altri si sono
'cancellati' dalla lista), il salvataggio non ha luogo. Se l'utente
non vuole salvare, esce dalla maschera con annulla.
Ammetto che non è il top delle soluzione, ma al momento ho
l'urgenza sulle spalle.
La soluzione losca che avevo trovato, ma che non usato, è
la seguente:
Quando l'utente A apre un record, in una cartella del programma
viene creato un piccolo vile che ha come nome l'ID del record
e il nome dell'utente.
Se l'utente B cerca di aprire un record, il programma controlla prima
che non esistano file che iniziano con l'ID del record scelto, quindi
il record non è bloccato.
Al posto di usare record o campi per il lock, uso piccoli file, il cui
tempo di scrittura è decisamente ridotto, e con esso anche i possibili
problemi.
Funzionava bene come cosa, ma non mi piaceva come soluzione.
Grazie tante per l'aiuto, spero di non scocciare più.
Saluti,
Pusky

 l'urgenza sulle spalle.
Come vuoi, non mi piace, è dispendioso e senza alcuna garanzia di successo
(ho detto nessuna).
Io credo che la soluzione (non certo l'unica) stia in quello che non hai
letto in modo approfondito.

 letto in modo approfondito.
Io non sono una cima. Poi di inglese sono proprio terra terra, comunque mi
sto rileggendo tutti i messaggi e spulciando qua e la, ma non trovo una
soluzione.
La mia soluzione in realtà non è una soluzione, nel senso che ho cambiato
logica di
funzionamento del programma. L'idea iniziale era quella di bloccare la
modifica di
un record aperto da un utente. Ora mi limito a gestire la 'coda' di accessi
in modifica
ad un record e segnalare se la modifica può essere salvata oppure no.
Comunque grazie.
Saluti,
Pusky

 ad un record e segnalare se la modifica può essere salvata oppure no.
La domanda è sempre quella: Che succede se due scrivono contemporaneamente
(lo so, non è possibile, ma da intendersi come "in momenti estremamente
ravvicinati")? Come organizzi l'ordinamento per garantire che il primo che
arriva "meglio si accomoda"?

 arriva "meglio si accomoda"?
Con la speranza che non mi crolli una 'certezza', se la tabella non contiene
indici,
chiavi o simili, l'ordine di lettura corrisponde all'ordine di scrittura
(spero...).
Quindi l'ordine di scrittura del record di 'blocco' corrisponde all'ordine
con cui
gli utenti potranno aggiornare il record.
Ordine che comunque PUO' non coincidere con quello di richiesta, per il
solito
motivo che a volte le scritture su db avvengono in differita e non in
diretta, comunque
avvengono...
Temo che mi ci voglia gia un'altra settimana di ferie o un'altra birra media
;-)
Ciao.
Pusky

 tempo), possono succedere 2 casi:
...
No, non deve accadere. Non funzionerebbe piů niente e avresti totalmente
ragione. Metti quel benedetto SP!
Se io leggo il mio record anche gli altri lo devono poter vedere.

 Metti quel benedetto SP!
cosě sappiamo anche se il sp fa effettivamente qualcosa
Salutoni
Sergio


Ola, ho messo il Service Pack 3 (piů di 30 minuti per installarsi
per vedere solo una nuova iconcina per l'aggiornamento
automatico :-))))), ma non cambia niente :'|
Comunque data la natura del programma in questione e dopo
averne parlato con ki di dovere... devo optare per la soluzione
che prevede la tabella con la lista degli utenti collegati.
Grazie a entrambi (CSSoft e Lupo) per l'aiuto.
Buona giornata
Pusky