PDA

Visualizza la versione completa : [DELPHI] CommitRetaining di un DataSet


123delphi321
28-01-2011, 23:04
delphi7 + firebird

ciao,

attualmente il mio programma funziona utilizzando il componente tibdataset dove leggo da una tabella del mio db dei record e poi li modifico...

ogni volta che effettuo il post di un record effettuo anche il commitreatening

funziona tutto bene....
pero',adesso ho la necessita' di modificare/inserire piu' record e poi confermare il tutto in un sol colpo.

ho la 'sensazione' che devo utilizzare ClientDataSet ( componente che non ho mai utilizzato ) e non riesco a capirne il funzionamento...

mi potete suggerire come procedere?

grazie

alka
03-02-2011, 12:16
Ogni volta che applichi modifiche ai dati, una transazione viene automaticamente avviata sul DB, poiché si tratta di un elemento imprescindibile per fornire il contesto nel quale viene inserita qualsiasi modifica apportata ai dati.

Quando esegui CommitRetaining, non fai altro che confermare la transazione che contiene le modifiche apportate ai dati dal tuo programma.

Invocare CommitRetaining ad ogni post equivale a confermare definitivamente ogni inserimento/modifica al record appena dopo che una di queste operazioni viene effettuata.

Se hai la necessità di inserire più record, anche in tabelle diverse, occorre innanzitutto evitare questo "automatismo" codificato, e gestire le cose in questo modo (salvo accorgimenti particolari dovuti al contesto in cui vengono applicate e di cui non sono a conoscenza):

[list=1]
avviare una nuova transazione quando si sta per consentire la modifica dei dati (c'è il componente IBTransaction che fornisce tutti i metodi necessari)
escludere la chiamata a CommitRetaining per ogni operazione, in modo da mantenere attiva la transazione corrente senza confermarla ad ogni modifica
consentire all'utente di fare tutte le modifiche, gli inserimenti e le eliminazioni previste dal programma
in fase di conferma dei dati inseriti da parte dell'utente, eseguire CommitRetaining per confermare la transazione corrente e le modifiche eseguite nel suo contesto
[/list=1]

L'uso del componente TClientDataSet che hai citato, nel contesto attuale, non è indispensabile poiché ha altre finalità: ad esempio, potrebbe essere utilizzato per lavorare con i dati esclusivamente in memoria e, al momento della conferma generale, 1) avviare una transazione, 2) salvare tutti i dati possibili, 3) confermare i dati inseriti con una Commit.

Mentre i componenti che utilizzi lavorano in modalità "connessa", il TClientDataSet ti permette di lavorare invece in modalità "disconnessa" (facendoti scaricare i dati dal server, lavorandoci senza essere collegato e infine, quando necessario, solo nel momento in cui il server database è disponibile, pubblicando le modifiche sul server).
Ma si tratta di un altra tematica, più legata all'architettura dell'applicazione rispetto a un semplice diverso utilizzo delle transazioni.

Ciao! :ciauz:

123delphi321
03-02-2011, 18:38
ciao e grazie.

se due utenti modificano lo stesso reecord senza eseguire il commitreatening vado incontro ad un eccezzione del tipo:

lock conflict on no wait transaction.
deadlock

praticamente prima che l'utente 2 possa effettuare commitreatening devo attendere che l'utente 1 effettui la propria commitreatening.

come devo gestire questa cosa da programma?

grazie

alka
03-02-2011, 18:52
Lo scenario è quello prospettato in questa FAQ (http://www.firebirdfaq.org/faq109/), che fornisce qualche indicazione a riguardo.

123delphi321
03-02-2011, 20:44
si, ho capito il problema.

ma adesso come va risolto?

se 2 utenti si mettono a fare modifiche sullo stesso dataset di dati, e ad esempio utente1 si allontana lasciando la transazione attiva per molto tempo; utente2 resta bloccato affinche utente 1 non conferma (e semmai conferma il giorno dopo)

non mi e' chiara che tecnica usare per evitare questi stalli


la mia transazione e':
read_committed
rec_version
nowait


grazie

alka
04-02-2011, 11:27
In questi casi, può tornare utile il componente TClientDataSet per poter gestire le modifiche in modalità "disconnessa".

La trattazione di questo componente e delle sue innumerevoli funzionalità è particolarmente ampia, quindi mi limito a fornirti i collegamenti a questi articoli di Cary Jensen, un po' datati ma sempre validi (poiché i meccanismi di lavoro del componente non sono mai cambiati) e in grado di fornire una panoramica completa delle caratteristiche.


A ClientDataSet in Every Database Application (http://edn.embarcadero.com/article/28876)
Defining a ClientDataSet's Structure Using FieldDefs (http://edn.embarcadero.com/article/28959)
Defining a ClientDataSet's Structure Using TFields (http://edn.embarcadero.com/article/29001)
Understanding ClientDataSet Indexes (http://edn.embarcadero.com/article/29056)
Navigating and Editing a ClientDataSet (http://edn.embarcadero.com/article/29122)
Searching a ClientDataSet (http://edn.embarcadero.com/article/29176)
ClientDataSet Aggregates and GroupState (http://edn.embarcadero.com/article/29272)
Deploying Applications that use ClientDataSets (http://edn.embarcadero.com/article/29297)
Cloning ClientDatSet Cursors (http://edn.embarcadero.com/article/29416)
Nesting DataSets in ClientDataSets (http://edn.embarcadero.com/article/29825)


Buon studio! :ciauz:

Loading