Newsgroup: it.comp.lang.visual-basic
Titolo: Transazioni

Vi pongo il mio quesito a breve dilemma. O meglio ... dovrò fare una cosa
del genere ... ma sto facendo altro, però ogni tanto mi capita di pensare
alla soluzione dell'ipotetico (ma verosimilmente reale - gioco di parole)
problema.
Scenario: x client connessi con loro copia allo stesso database.
due client si collegano secondo più secondo meno alla stessa tabella per
tirare giù dei valori, quindi di li sceglierne uno e utilizzarlo. Supponiamo
che A arrivi per primo, lo scelga e se lo ritrovi sul suo form (allo stato
attuale non prevedo di fargli fare operazioni effettive sul db).
Ora A si assenta .. e intanto B decide di usare lo stesso record di A ...
immancabilmente il database non potrebbe soddisfare le due richieste ... e
qualcosa mi ritornerebbe con poca integrità referenziale ...
Avevo pensato - considerando che il mio misero db è attualmente un access
2000 - due soluzioni.
La prima ... A legge la tabella ... quando sceglie il record y ... fare
contestualmente un update su di un campo flag che marcato come u ... sta ad
indicare che è in uso ... e pertanto quando B legge la sua tabella ... il
record x non compare.
La seconda soluzione ... lasciare che A e B vedano entrambe la stessa cosa
... ma il primo dei due che preme un tasto conferma può effettivamente
utilizzare y ... con l'accortezza alla pressione del tasto di fare una query
secca sulla tabella dove sta y ..... e verificare la sua disponibilità.
Con sql server si potrebbe bloccare il record (anche se non sò come si
faccia) ... ma con access non mi viene in mente altro. Soluzioni? Consigli?
Le due soluzioni, ahimè presentano un margine di imprevedibilità ... qualora
due utenti, contemporaneamtne, ammessi tutti i fattori che volete, riescano
ad inviare la stessa richiesta allo stesso secondo ... ma penso sia un caso
limite. Mi piacerebbe sapere se vi si è mai presentato il problema e come
l'avete risolto. Tutto ciò premesso ... delle belle transaction che mi
gestiscano il beneficio dell'errore su qualche imprevisto nella procedura.
Ciao e grazie a tutti. Andrea

 secca sulla tabella dove sta y ..... e verificare la sua disponibilità.
In che senso disponibilita' ? Se il record, come penso, non e' stato
bloccato, l' update e' disponibile per il primo che arriva.
Forse potrebbe essere utile un meccanismo che, quando il secondo cerca di
fare l' update, verifichi se il record che ha nel buffer e' ancora uguale a
quello che e' nel database. Se e' uguale allora l' update va giu'
tranquillamente, mentre se e' diverso (cioe' almeno un campo e ' cambiato)
viene avvertito l' utente che cio' che vede sullo schermo non corrisponde a
quanto salvato nel database.
(...)
Ciao
Aldo

 wrote

mica solo per loro... o meglio, fastidiosa e' un bell'eufemismo :)
-- c ha versato 5 milioni (rec1), poi ne ha prelevati 50 (rec2).
-- a legge rec2.
-- b fa una query e trova solo rec1: allegramente concede quindi un prestito
a c, subito prima di essere licenziato dal direttore della filiale.
gli scenari devono rispecchiare il mondo reale, cioe' le esigenze degli
utenti, non quelle dei programmatori. noi -- ho il cappellino del
programmatore finche roal e hellboy non me lo tirano via a colpi di linux e
c++ -- non esistiamo :)






Ne deduco che il sistema che ho deciso di adottare 
sia il più verosibile e respecchi la realtà.


Hal1961 ?? Confido in te ... e nella risposta 
criptica ... affinchè il direttore non licenzi l'impiegato.


Ora, a me non mi licenzia nessuno, però mi 
piacerebbe tirare su qualcosa di serio e di efficente, che non devo andarci a 
rimettere le mani tra due mesi.


 


Ciao Andrea



Ho dovuto affrontare lo stesso problema un po' di mesi fa,
la soluzione che ho adottato per ora si sta verificando 
efficace e spero che continui ad esserlo:
- nel database su server ho creato una tabella (LOCK) con la
  quale memorizzo le informazioni relative ai record
  in uso, così definita:
  TABELLA   (nome della tabella su cui opero)
  RECORD    (campo contatore del record in uso)
  UTENTE    (nome utente che usa il record)
  DATA      (data e ora di blocco del record)
- ogni volta che un utente tenta di entrare in nella
  maschera in modifica o annullamento verifico che il
  record che vuole trattare non sia già bloccato da un altro
  utente.
- la data serve per sapere se il record è bloccato da più
  di un certo limite di tempo (io uso di solito 5 min).
- se l'utente A tenta di entrare in modifica di un record
  bloccato dall'utente B e sono passati meno di 5 min. dal
  momento del blocco l'utente A riceve un messaggio che
  lo informa di non poter operare sul record se non in
  visualizzazione, altrimenti se il record è bloccato da più
  di 5 min. nella tabella LOCK viene modificato il codice
  utente B con A, quindi A potrà entrare in modifica del
  record precedentemente bloccato da B. Quando B tenterà
  di confermare le modifiche effettuate riceverà un
  messaggio che lo informerà di aggiornare i dati in quanto
  il record in questione è stato sbloccato e modificato
  dall'utente A. Perchè questa complicazione di sbloccare
  il record dopo un tot di tempo ???
  Se va via la corrente mentre ho bloccato un record chi
  lo modifica più ???
  E' l'unica soluzione che ho trovato e per ora sta
  funzionando correttamente senza problemi.
Ho descritto molto a grandi linee come ho affrontato il
problema della gestione del database in rete, anche se
i controlli effettuati sono molti di più di quelli descritti
nel post...
..tutto ciò che riguarda questa gestione l'ho comunque
racchiuso all'interno di una classe; ciò mi ha permesso
di incapsulare il tutto e di rendere più chiaro il codice.
Ciao Stefano ;-)
--
TiscaliNet, libero accesso ad Internet.
http://www.tiscalinet.it
-- 
Posted from 
laguna.tiscalinet.it
 [195.130.224.86] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Scusa dimenticavo,
naturalmente alla partenza del programma ho fatto in modo
che il client impostasse in automatico la data e orario
corrente con quella del server.
Ciao Stefano


quanto salvato nel database.
problema per questa soluzione : 
A guarda la tabella X
B guarda la tabella X
A modifica un record (tipo sottrae 1 ad una giacenza, classico
esempio, che arriva a 0)
B vede ancora quel record con giacenza 1 e a modo suo modifica pure...
che succede a questo punto?
Una soluzione BARBARA sarebbe un pulsante "refresh" per avere l'update
prima di ogni modifica (ma torniamo a prima, spostiamo solo un po' il
"culo" dell'utente che si prende la briga di controllare quando vuole
fare qualcosa) o meglio ancora si controlla in qualche maniera se tale
record non e' stato modificato e in caso a che valore... ma COME FARE
STA COSETTA ? 

 wrote in message
news:913kat$2pd9b$1...@ID-61006.news.dfncis.de...


Onestamente non credo che il modo migliore per imporre i blocchi dei record
sia quello di aggiornare altri record perché in fin dei conti si potrebbe
avere lo stesso problema di concorrenza anche su questi ultimi.
Personalmente utilizzo questa tecnica (che è abbastanza complessa da
progettare ma semplice da utilizzare) :
Definisco un computer Server, dove installo un componente remoto che funge
da centrale di smistamento messaggi; quando modifico un record o una tabella
o una serie di tabelle, avverto tutti i client dell'aggiornamento (quindi
non vado a testare sul DB), generando un evento codificato.
In pratica tale evento non è altro che una richiesta (a tutti gli altri
client) di consenso per la modifica. Ogni client quindi deve rispondere
acconsentendo affinché la modifica abbia luogo.
Terminata la modifica, verrà generato un nuovo evento, a tutti gli altri
client, di "operazione completata". I client stessi reagiranno aggiornando
le proprie visualizzazioni.
Se per esempio A richiede di modificare un record e mentre aspetta conferma
riceve un evento di richiesta di aggiornamento da parte di B, sia A che B
vengono informati della richiesta simultanea e viene chiesto loro di provare
a rieseguire l'operazione; sarà a questo punto l'utente più veloce ad avere
accesso per primo alla modifica.
Potrebbe succedere inoltre che un utente decida di sconnettersi proprio
durante l'attesa di risposta e che quindi l'evento "operazione completata"
non venga mai generato. Un TimeOut di x minuti, verificherà la presenza del
client che ha effettuato la richiesta per poi decidere se generare
autonomamente l'evento "operazione completata" ...
Al di là di ogni strategia utilizzata .. io credo che una perfetta gestione
delle concorrenze non esista nella pratica della programmazione;
soprattutto, ogni soluzione avrà i suoi problemi di scalabilità (nel mio
caso ho calcolato che più di 10 client potrebbero causare un overhead
inaccettabile a tutti i client) e portabilità (non è sempre possibile
utilizzare gli strumenti che vogliamo .. vero ?) che ci renderanno la vita
sempre più difficile ...
Un saluto festoso a tutti ...
Davide
In realtà sono ancora in fase di sviluppo di quest'ultimo caso.

 wrote in message
news:91cshj$e0n$1...@fe1.cs.interbusiness.it...


 catena di timeout) senza il lock di tabella...
Ok ... buona soluzione .. ma non sono solo questi i motivi della mia
affermazione .. per esempio se esegui una query di aggiornamento su 2 o +
tabelle devi andare a creare i record di blocco solo per i campi interessati
ecc...
Continuo a ripetere che non è una soluzione malvagia la tua né che la mia
sia migliore ... io preferisco "chiedere prima di eseguire" mentre tu
"esegui solo se è possibile" ... l'obbiettivo è lo stesso, gli strumenti
cambiano ... il buon risultato è una speranza !
Saluti