Domanda

Qual è il modo preferibile scrivere applicazioni di database Delphi che utilizzano transazioni e anche componenti data-aware?

Devo scrivere un'applicazione client che accedono InnoDB tavoli, e fare un po 'master-detail tipo di cose all'interno transazioni. Dopo aver fatto qualche ricerca su transazioni (dal punto di vista generale), poi umilmente fare una conclusione che non in grado di riconoscere i dati componenti e SQL codificati a mano sarebbe la "partita perfetta" delle operazioni; Ma i componenti data-aware non sarebbero. Essi non sembrano fatti uno per l'altro.

Ho la reale necessità di operazioni di impiego, ma d'altra parte non ho potuto solo gettare i componenti data-aware via perché le cose di semplificare.

Potrebbe qualcuno si prega di illuminarmi? Sono stato googling, ma non ho trovato una soluzione utile. Forse perché il mio inglese non è abbastanza buono che le mie parole chiave sono limitati.

A proposito, sto usando Delphi 7 e valutando UniDAC come la libreria di accesso ai dati.

Grazie.

Modifica

Esempio per descrivere un aspetto della mia domanda:

Immaginate un modulo con 2 DBGrids su di esso. La prima griglia è MasterGrid e al di sopra di esso sono questi pulsanti: Aggiungi, Modifica e Cancella. La seconda griglia è DetailGrid. Se l'utente fa clic su Aggiungi allora che entra in questo modo:

  • Connection.StartTransaction
  • Master.Append quindi Master.Post poi Master.Edit (in modo che il set di dati master ha la chiave primaria AutoIncrement, ed è modificabile ora)
  • Mostra il modulo di editing modale, in cui l'utente riempie i dati anagrafici, e anche aggiungere alcuni record di dettaglio utilizzando un altro modulo.
  • Se l'utente fare clic su OK, l'applicazione avrebbe fatto Master.Post e Connection.Commit. Se l'utente clicca su Annulla, quindi l'applicazione farebbe Connection.Rollback.

So che le transazioni devono essere il più breve possibile, ma si può vedere sopra che l'operazione è soltanto il più breve la velocità degli utenti compilando il modulo.

Se fossi utilizzando componenti non data-aware, mi avrebbe fatto su misura inserto SQLs basate dall'input dell'utente, quindi eseguire il codice SQL tra lo StartTransaction e impegnarsi. Così posso ottenere molto breve transazione.

Modifica 2

Ringrazio tutti voi per la vostra gentile partecipazione. Io scelgo la risposta da vcldeveloper perché è la soluzione più vicina al mio bisogno di corrente.

È stato utile?

Soluzione

Altri menzionato utilizzando una combinazione di DataSetProvider e ClientDataSet per avere un aggiornamento batch, ma in caso di utilizzo di componenti ADO o UniDAC, non è necessario l'ulteriore livello di DataSetProvider + ClientDataSet, perché entrambi gli aggiornamenti in lotti di sostegno ADO e UniDAC.

ADO , che cosa si dovrebbe fare è impostare LockType del set di dati di ltBatchOptimistic . Per UniDAC , si dovrebbe impostare CacheUpdate di proprietà di True .

Questa modifica rende il vostro set di dati per memorizzare nella cache tutte le modifiche apportate sul suo set di record in memoria, e li alltogether spedire database solo quando si chiama UpdateBatch Metodo (ADO) o ApplyUpdates metodo (UniDAC).

Ora che cosa si dovrebbe fare è di lasciare il vostro inserto utente / modificare un record nel master set di dati e tutto ciò incide / lei vuole nei dettagli DataSet utilizzando qualsiasi componenti data-aware che ti piace. Tutte le modifiche saranno memorizzate nella cache. Quando l'utente è fatto, è possibile avviare una nuova transazione, e il primo UpdateBatch chiamata (o ApplyUpdate in caso di UniDAC) per il master set di dati, e quindi per i dettagli set di dati, e se tutto va bene, il commit della transazione.

Questo renderà le vostre operazioni a breve senza bisogno l'ulteriore livello di ClientDataSet.

Saluti

Altri suggerimenti

Capisco la tua domanda, penso. Quando si apre un TADODataSet con es 10 righe di dati da modificare in una maschera, con componenti di dati di riconoscere, vi sono situazioni in cui si vorrebbe cache tutte le modifiche apportate a tutte le 10 righe (e possibilmente delezioni e inserzioni) e impegnarsi come un lotto . Non è possibile aprire la transazione sul primo cambiamento, perché sarebbe bloccare altri utenti che cambiano gli stessi dati. Le operazioni devono essere il più breve possibile.

Quello che faccio nello scenario abbozzato è utilizzare i seguenti componenti in una catena:

>> TADOConnection TADODataSet >> >> TDataSetProvider TClientDataSet >> >> TDataSource TDBEdits etc.

Ora tutte le modifiche vengono memorizzati nella cache in TClientDataSet e si può chiamare di metodo ApplyUpdates di inviare tutte le modifiche in una transazione veloce. Presente che è anche possibile utilizzare più TADODataSets e molteplici TClientDataSets per un master-detail struttura (-detail-ecc) con set di dati nidificati. Tutte le modifiche master-detail possono anche essere memorizzati nella cache e applicate in un unico lotto in una transazione. Vedere l'aiuto e le risorse altrove per tutti i dettagli sull'implementazione di questo. In un primo momento non è facile. Ma se si capito è facile e offre tonnellate di possibilità. (Editing offline, esaminando le modifiche prima di applicarle, ecc.)

Per evitare la necessità di eseguire transazioni di grandi dimensioni che uso DataSetProviders e ClientDatasets (anche a livello locale).

Si consideri di utilizzare questo come una sorta di cache e ti dà il meglio di entrambi i mondi. È possibile utilizzare i controlli data-aware per semplificare le cose mentre si lavora su l'interfaccia utente. Azioni utente oltre i set di dati sono "registrati" dai ClientDataSets (tipo di cache del database).

Quando l'utente è pronto a Salva le modifiche al database (ad esempio, i dati della fattura è tutto a posto), si chiama il ApplyUpdates metodo per il set di dati (S).

Nello scenario più semplice, dove tutti i set di dati sono in master-detail relazioni (nidificato dal fornitore), il provider si avvia e commit / rollback della transazione di per sé, quindi sei in una situazione tutto o niente automaticamente.

Se si dispone di relazioni più complesse, è possibile chiamare StartTransaction prima di iniziare l'applicazione degli aggiornamenti per ogni set ClientDataSet coinvolte, e alla fine chiamata Commit o rollback, se necessario). La logica per il provider è se la connessione ha una transazione attiva quando ApplyUpdates è chiamato, quindi non fa nulla con la transazione, ma cambia semplicemente pubblicare nel database, ipotizzando sei in controllo della transazione.

Si deve leggere su TClientDataSet e come gestire l'OnReconcileError e sperimentare con la tecnologia prima di metterlo in ambienti di produzione, ma funziona molto, molto bene per me.

I miei 2 centesimi.

È assolutamente giusto che una scrittura di transazione deve essere il più breve possibile, e non dovrebbe essere vivo per tutto il tempo mentre un utente sta riempiendo il formulario.

La soluzione generale, come già risposto, è quello di utilizzare un livello intermedio (un ClientDataSet). Ma il vero problema con il vostro scenario è che non si può ottenere un valore autoincrement per la tabella Maestro senza Master.Append e Master.Post, e di conseguenza si avvia un scrittura delle transazioni a lungo prima che è effettivamente necessaria.

Quindi, se non si desidera utilizzare il livello intermedio e continuare a utilizzare componenti data-aware con brevi scrittura le transazioni si dovrebbe pensare di un database che supporta l'ottenimento di un valore autoincremented senza eseguire INSERT (a tabella master). L'esempio è Firebird di database e componenti di accesso ai dati FIBPlus per Firebird supportano completamente questa funzione.

Le transazioni dovrebbe essere il più breve necessarie . Il problema è come database diversi maniglia di bloccaggio. Database che eseguono solo a livello di riga blocco e può tornare immediatamente da una serratura senza aspettare sono molto meno probabilty a un punto morto. Di solito inserti sono meno problematici (anche se un altro utente non vedrà nuove righe fino impegnati, a seconda del livello di isolamento), gli aggiornamenti e le eliminazioni sono più problematici. Commettere troppo spesso potrebbe essere "cattivo" come bene. Caching cambiamenti e la loro applicazione in un unico operazioni è un'altra possibilità - ma bisogna problemi maniglia a causa di altri utenti che cambiano record nel frattempo. Non c'è una soluzione "migliore" - tutto dipende dalle esigenze effettive. Per alcune applicazioni (e alcune banche dati) mantenendo il record bloccati fintanto che stanno cambiando è ok, per gli altri non possono. aggiornamenti batch possono essere ok in alcuni scenari e non in altri. È necessario selezionare il modello che funziona meglio per la vostra applicazione e il database.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top