Newsgroup: it.comp.lang.delphi
Titolo: query live

Sto usando un db Access con componenti ADO (TADODataset+TADOConnection) (su 
cui sono molto ignorante).
Il db può essere letto/modificato contemporaneamente da due postazioni.
Vorrei che se la postazione A modifica un record, B se ne accorga e non so 
come fare.
In internet ho visto cose come TQuery.RequestLive, TUpdateSQL, ma mi 
sembrano tutte cose per BDE... o cmq non so riutilizzarle con ADO.
Inoltre ho letto che non conviene fare query live...
Secondo voi come posso affrontare questa esigenza?
Graze
-- 
Ing. Gianni Franceschet
g.fran...@logiconsulting.it
in...@logiconsulting.it
LogiConsulting s.r.l.
via Arrivabene 2,
ATTENZIONE: questo documento è indirizzato esclusivamente al destinatario !
A chi lo riceve è imposto il rispetto di quanto previsto dal D.Lgs. 196/2003 
in materia di Privacy.
Chi ricevesse per errore questo documento è pregato di contattere il 
mittente ed eliminare il doumento stesso con tutto il suo contenuto. Grazie.
46100 Mantova - Italy
Tel. 
+39 0376329943
Fax 
+39 0376221237
 

come fare.
Perché ? non è il modo corretto di operare.  Il modo corretto di
scrivere un'applicazione di gestione dati multiutente è che i dataset
siano liberi di poter operare per conto proprio in locale; sarà il
server a risolvere, eventualmente, casi di conflitto.  Inoltre, per
"live" si intende semplicemente un dataset modificabile.  Ci sono
condizioni, infatti, nelle quali potrebbe non aver senso modificare il
dataset restituito da una query e quindi si "mappa" un'operazione di
update su determinate operazioni gestite mediante TUpdateSQL.

 update su determinate operazioni gestite mediante TUpdateSQL.
Ok.

la modifica solo se fa il refresh della query (uso TADODATASET). Mi sbaglio?
No, non ti sbagli.  La chiave è nel capire perché il secondo utente ha
bisogno di vedere i dati aggiornati in tempo reale.  La cosa potrebbe
anche avere un senso in contesti precisi: vorrei sapere se il tuo è
uno di questi.

 uno di questi.
Spero di essere abbastanza chiaro, dato che le mie idee non lo sono per 
nulla.
Il programma è un gestionale. La questione di vedere in tempo reale 
l'aggiornamento non è vitale: se due stanno guardando lo stesso archivio, 
p.e. quello dei movimenti contabili o la situazione di magazzino, e uno dei 
due apporta una modifica, mi piacerebbe che il secondo la vedesse senza 
troppe complicazioni.
Se esiste un modo semplice, lo prendo in considerazione, altrimenti rinuncio 
e opto per qualcosa come un bottone "refresh" insegnando all'utente che 
quella che sta vedendo è solo una fotografia istantanea dell'archivio, ma 
che può diventare obsoleta.
L'uso della proprietà LockType mi permette di avere eccezzioni quando il 
secondo utente tenta di modificare lo stesso record del primo: in questo 
momento sono costretto a fare un refresh, il che mi sta bene, ma come faccio 
a sapere che l'eccezione è proprio questa? (L'eccezione che ricevo è 
calssname=EDatabaseerror... mi sembra un po' generica). Inoltre, 
l'eccezzione ce l'ho nel post.... mi piacerebbe saperlo prima se sto 
modificando un record già modificato da altri.
La cosa la stavo vedendo anche in prospettiva di un altro fatto che per 
inesperienza non so come si può gestire al meglio. Supponiamo che un utente 
compili un documento (es una fattura) e lo salvi: questa operazione va a 
toccare in realtà varie tabelle e chiudo tutto dentro una transaction. A 
questo punto vorrei essere sicuro che durante la transaction altri utenti 
siano inibiti alla scrittura del db, per mantenere congruenti alcune 
relazioni che questa transaction sta modificando e sulla base delle quali 
gli altri non devono in questo momento fare conto (ma dovranno rinfrescare). 
Come farlo e come rendermi conto, poi, che un altro utente deve 
"rinfrescare" i propri dati?
Gianni 

 siano inibiti alla scrittura del db
Sbagliato: in un contesto multiutente non devi "inibire" nulla a nessuno
(altrimenti che multiutenza è ?).  Le transazioni hanno livelli di
isolamento appositi per evitare problemi tra le diverse operazioni di
utenti distinti.  Con una transazione di tipo "READ COMMITTED", ad
esempio, gli utente A e B non vedono i dati definitivi di C, finché C non
ha provveduto a un "commit".  
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 (altrimenti che multiutenza è ?).
Fammi capire meglio. Ti faccio un paio di esempi i cui mi posso trovare.
Es1. Premessa: la compilazione di una fattura è un processo lungo: gli edit 
in maschera raccolgono i dati, poi alla conferma porto il db in edit/insert, 
aggiorno i campi e posto (previo verifiche varie), cioè non tengo il db in 
edit e non lavoro con edit lincati direttamente ai singoli campi, ma ho 
varie maschere da riempire con edit normali e lavoro sul db tutto in un 
colpo.
Se due postazioni compilano una fattura, il numero del documento viene 
ricavato dall'archivio movimenti: se lo fanno contemporaneamente, entrambi 
in maschera avranno una proposta tipo "num.doc = 16". Il primo che arriva a 
salvare ok, l'altro, non deve salvare perchè quel 16 è diventato 
inconsistente e il programma non deve fare nulla, se non riproporre l'input 
con proposta "num. doc = 17" e aspettare una nuova conferma dell'utente.  NB 
che in questo caso NON stiamo parlando di conflitti sullo stesso record, 
perchè le due fatture generaro due nuovi record diversi (anche i movimenti 
che ne conseguono sono nuovi e diversi tra loro), in pratica sono due 
Insert, però per me è un conflitto lo stesso.
Es.2 Una fattura, quando salvata va a movimentare alcuni conti. Supponi che 
un conto che vale X venga incrementato dalla fattura del primo utente di Y, 
e dalla fattura del secondo di Z: il primo tenta di postare qualcosa come 
X+Y, il secondo qualcosa come X+Z. Il secondo non deve riuscirci perchè, 
avendo incrementato il conto già di Y, il secondo dovrebbe semmai postare 
qualcosa come X+Y+Z, cioè deve rileggere il valore giusto prima di 
rieseguire il calcolo.
Avevo quindi pensato a qualcosa che mi permettesse di:
- bloccare per qualche istante la sola scrittura del db
- eseguire i miei controlli (es il num.doc 16 è ancora un dato valido): se 
si postare (else sbloccare e gestire)
- sbloccare anche per gli altri
Es.1 Il primo arriva alla fine, il secondo che arriva vedrebbe il 16 come 
dato non più valido perchè già "occupato".
Es.2 Il primo arriva alla fine, il secondo mi da eccezione perchè trova un 
record diverso da quello di partenza
Suppongo che questo sia un omdo antiquato di risolvere la questione.... 
help.
Gianni 

Suppongo che questo sia un omdo antiquato di risolvere la questione.... 
Decisamente.

 Decisamente.
Ne avevo il sospetto. Dove, come posso apprenderne di migliori? Qui mi sa 
che mi serve un bel aggiornamento sull'uso dei DB....
Grazie, Gianni 

 sotto una transaction. 
Brrr... quello che dovresti fare, invece, è un UPDATE incrementando o
decrementando il valore.  Nel modo in cui fai tu, aumenti inutilmente la
criticità del sistema.


Ti ringrazio caldamente.
Un'ultima domanda, ho cercato qualcosa sui db e sulla multiutenza e trovo un 
bailame di libri ed articoli.
Avresti dei testi/link da consigliarmi, più che altro sulla gestione 
mutliutenza e connessi problemi.
So che è un argomneto difficile e spesso legato ai componenti che si usano, 
ma insomma devo partire da qualche parte...
Ciao Gianni 

 mutliutenza e connessi problemi.
A parte libri conosciuti sui database(*), c'è un mare di articoli
riguardante le transazioni, i loro livelli di isolamento e gli optimistic
e pessimistic locking.
In particolare:
http://en.wikipedia.org/wiki/Database_transaction
http://en.wikipedia.org/wiki/ACID
http://databases.about.com/od/specificproducts/a/acid.htm
http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_lock_records
(*) 
"Introduction To Database Systems" 8^ ed. - C.J.Date
"Databases, Types and The Relational Model" - C.J.Date
