Newsgroup: it.comp.lang.delphi
Titolo: [D7][Firebird 1.5] Campo Generatore Con Buchi

Una buona serata a tutti,
 
non so se è un problema di delphi o firebird o quant'altro.
 
Ieri mio cognato ( tanto per cambiare ) mi chiama e mi fa : mi sono accorto che la numerazione delle attività ha un buco di ben 4 numeri, chiaramente questa cosa non è mai successa prima. Praticamente dalla ATTIVITA_ID 3214 si passa a 3218.
 
Nel programma eseguo la seguente istruzione :
 
nNumero_Attivita := DM.DB_Master.Gen_Id('GEN_OPZIONI_ID',1);
 
dove DM è il Data Module, mentre il DB_Master è l'oggetto database. Utilizzo da anni e con soddisfazione i componenti FIBPlus per l'accesso a Firebird.
 
Tale campo ( nNumero_Attivita ) lo scrivo poi in un'altra tabella ed è un campo autoincrementato tramite il generatore GEN_OPZIONI_ID.
 
Secondo voi quale potrebbe essere l'anomalia, io ho pensato a qualcosa nella rete, tipo un salto di connessione ( sparo ) o altro.
 
Tale operazione viene fatta all'inizio di una serie di operazioni su db, lastruttura è la seguente :
 
    if not TQ_Appoggio.Transaction.InTransaction then
       TQ_Appoggio.Transaction.StartTransaction;
 
       nNumero_Attivita := DM.DB_Master.Gen_Id('GEN_OPZIONI_ID',1);
 
       update tabella xxx
 
       insert tabella yyy
 
       insert tabella zzz
 
       TQ_Appoggio.Transaction.CommitRetaining;
 
Un grazie sentito a chi mi dirà qualcosa in merito.
 
Ciao da Enrico Giudici c/o anthelios
 

Domanda: è cosi' rilevante che la numerazione sia precisa?
A parte cio. onestamente non ricordo se un calcolo basato su gen_id può essere incluso in una eventuale rollback di una transazione.
 
Sulla rete sono scettico. 
Le connessioni db sono abbstanza delicate e se la rete andasse giu' non funzionerebbe piu nulla, dopo.
 
 
A.

 Domanda: è cosi' rilevante che la numerazione sia precisa?
 
Si, non ci devono essere "buchi" di numerazione.
 
La cosa strana è che una volta avuto il progressivo nuovo effettuo update ed insert all'interno di una transazione così da essere sicuro che se va male qualcosa non fa nulla.
 
Ciao e grazie ancora, speriamo di vederci presto.

 Si, non ci devono essere "buchi" di numerazione.
 
In questo caso, io userei uno strumento differente dal generatore, tipo un MAX(colonna), poiché il GENERATOR viene sempre incrementato indipendentemente dalla transazione per garantire la fornitura di un valore univoco a qualsiasi utente collegato.
 
Ciao,
  Marco.
 
-- 
MARCO BREVEGLIERI (Software and Web Developer)
 #Home: 
http://www.marco.breveglieri.name
 
 #Blog: 
http://www.compilaquindiva.com
 
 #DelphiPodcast: 
http://www.delphipodcast.com
 

 MAX(colonna)
 
 
A parte che le prestazioni peggiorano all'aumentare del numero di record, non è garantita l'univocita. 
Se io e te facciamo la stessa operazione nello stesso momento leggiamo max=100.
 
Poi, tu che sei arrivato prima di me fai la insert e funziona, ma io avro' la violazione dell'ovvio (ma non per tutti) constraint di primary key.
 
Se il generator non è adatto, l'unica è una tabella di contatori, ihmo.
 
A.

 Se il generator non è adatto, l'unica è una tabella di contatori, ihmo.
 
Potrebbe essere un idea valida.
 
Ciao e grazie da Enrico.

 
 
infatti mi aspetto che la generazione del numero venga fatto "atomicamente", in questo caso anche se più utenti accedono alla stessa porzione di codice ognuno ha il suo bel numerello che poi viene utilizzato per inserirlo in una tabella.
 
Sta di fatto che è la prima volta in moltissimi anni che a mio cognato gli capita una cosa del genere, tieni presente che ogni giorno più utenti ( suoi collaboratori ) accedono a tale funzionalità.


 Se il generator non è adatto, l'unica è una tabella di contatori, ihmo.
 
Anche questa può essere una soluzione.
E comunque, se non gestisci l'accesso alla tabella nel modo opportuno, anche in questo caso rischieresti comunque una "key violation".


 Concordo in pieno.
 
Prima di concordare, fai una prova di prestazioni con un numero elevato di record, e vediamo se è vero. ;)


 
 
concordavo in pieno il discorso che non mi sembrava molto robusto per il discorso che faceva Alberto con possibilità di stessa chiave. Sono d'accordo con te che potrebbe essere anche la tua una soluzione praticabile, solo che nel mio caso andrebbe rivisto il codice e la struttura del db per attuarlo.
 
Come dicevo prima, sono anni che tale sistema permette la sequenza di chiavi anche ( e sopratutto ) in multiutenza, non capisco come è potuto succedere. La cosa più logica che ho pensato è qualcosa sulla rete ma sinceramente non mi capacito.
 
Un grazie ancora Marco per la tua disponibilità e supporto.
 
Ciao da Enrico.

 Come dicevo prima, sono anni che tale sistema permette la sequenza di chiavi anche ( e sopratutto ) in multiutenza, non capisco come è potuto succedere. La cosa più logica che ho pensato è qualcosa sulla rete ma sinceramente non mi capacito.
 
Se acquisisci un nuovo numero dal generatore per appiopparlo a un record, e fallisce il salvataggio di quest'ultimo, ripetendo l'operazione otterrai il numero di nuovo incrementato.
 
Ogni volta che leggi il generatore, a prescindere dall'utente e da una eventuale transazione attiva o meno, incrementi il registro e prendi il numero successivo.
 
Se non devi lasciare buchi, il generatore non è lo strumento ideale, e se lasci dei "buchi" devi resettarlo a un valore diverso per far ripartire la numerazione da un certo valore in poi.
 
Meglio una tabella con dei registri contatori più flessibili (ad esempio, io ne uso alcune con anno e numero, in modo da resettare il secondo quando cambia il primo) oppure usare come dicevo il MAX.
 
Supponendo che il punto in cui leggi il generatore sia "wrappato" dentro una stored procedure o un metodo, non dovrebbe essere nemmeno troppo difficile cambiarne l'implementazione.
 
Ciao,
  Marco.


 
 
sono d'accordo.
 
Ciao da Enrico.