* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Aprile 16, 2024, 08:40:59 pm

Inserisci il nome utente, la password e la durata della sessione.

73 Visitatori, 0 Utenti

Autore Topic: Aiuto, perdo record  (Letto 2971 volte)

tito_livio

  • Full Member
  • ***
  • Post: 146
  • Karma: +3/-0
Aiuto, perdo record
« il: Agosto 08, 2022, 01:02:23 pm »
Buongiorno a tutti,
in un nuovo progetto, ho un database Mysql con diverse tabelle, di tipo MyIsam, alle quali accedono alcuni client, anche una decina, con dei mie programmi.
Il problema è che, circa l'uno percento dei record aggiunti, non vengono poi ritrovati.
Essendo che ci sono tabelle anche con 900.000 record, il problema diventa frequente.
I programmi girano sotto Windows 64 bit e 32 bit, sono compilati per 32 bit con la versione 2.0.6.
Uso i componenti nativi, non quelli Zeos, e il codice che uso per salvare segue questo semplice schema:

Codice: [Seleziona]
          fdm.tesiti.AppendRecord([....]);
          fdm.tesiti.applyupdates(8);
          fdm.lab_anno.transaction.commitretaining;
          fdm.tesiti.Close;
          fdm.tesiti.Open;

L'argomento 8 della funzione applyupdates è stato inserito per cercare di correggere il problema ma non risolve.
Grazie in anticipo.

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Aiuto, perdo record
« Risposta #1 il: Agosto 08, 2022, 02:10:31 pm »
Ciao, premettendo che non conosco MySql così bene da poterti dare una mano concreta, ti chiedo comunque alcune info:

1) Hai detto che ci sono diversi client, come comunicano i client con il database ?

2) Perchè non hai aggiornato almeno ad una versione più recente Lazarus e FPC ?

Il fatto che usi commitretaining mi fà sorgere un dubbio: MySql server non supporta più transazioni contemporanee sulla stessa connessione, e commitretaining lascia aperta la transaction .... Se la usi con i Thread o su più Tabelle contemporaneamente, forse quello è il problema.

Ciao
Magari sbaglio ....
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

tito_livio

  • Full Member
  • ***
  • Post: 146
  • Karma: +3/-0
Re:Aiuto, perdo record
« Risposta #2 il: Agosto 08, 2022, 03:10:14 pm »
Ciao,
i vari client accedono, in rete locale, al database tramite le librerie native Lazarus.
Non ho aggiornato ancora Lazarus perché pensavo fosse un errore mio e perché spesso ci sono dei problemi di compatibilità fra vecchie e nuove versioni.
A questo punto però è una prova che farò.
Per quanto riguarda le transaction, credo che non sia quello il problema perché il motore Mysql utilizzato è Myisam che non gestisce le transazioni. 
Proverò quindi con una versione aggiornata di lazarus e vedremo.
Grazie.

tito_livio

  • Full Member
  • ***
  • Post: 146
  • Karma: +3/-0
Re:Aiuto, perdo record
« Risposta #3 il: Agosto 08, 2022, 03:18:54 pm »
Aggiungo, una cosa che ho ricordato adesso, che potrebbe aiutare a chiarire la situazione.
La stessa cosa mi succedeva con un vecchio progetto in Delphi3 che accedeva a Mysql con gli ODBC.

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Aiuto, perdo record
« Risposta #4 il: Agosto 08, 2022, 05:42:24 pm »
Aggiungo, una cosa che ho ricordato adesso, che potrebbe aiutare a chiarire la situazione.
La stessa cosa mi succedeva con un vecchio progetto in Delphi3 che accedeva a Mysql con gli ODBC.

Bhè Delphi3 con ODBC .... eravamo all'alba di un nuovo impero (e nel film sono tutti morti ....  ::) )
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Aiuto, perdo record
« Risposta #5 il: Agosto 08, 2022, 05:47:25 pm »
Codice: [Seleziona]
          fdm.tesiti.AppendRecord([....]);
          fdm.tesiti.applyupdates(8);
          fdm.lab_anno.transaction.commitretaining;
          fdm.tesiti.Close;
          fdm.tesiti.Open;

Ora ho notato una cosa: usi "lab_anno" per le commit e "tesiti" per inserire i dati ?
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1300
  • Karma: +10/-1
Re:Aiuto, perdo record
« Risposta #6 il: Agosto 09, 2022, 08:03:39 am »
Ciao,
oltre alla verifica suggerita da DragoRosso, io ho un unico progetto in cui vado a scrivere il DB, che tra l'altro è MSSql. Le istruzioni che uso sono queste:
Codice: [Seleziona]
        //Ora posso fare la sostituzione.
        //Preparo l'istruzione SQL
        SqlQueryUpdate.UpdateSQL.Clear;
        SqlQueryUpdate.UpdateSQL.Add('update ' + CstNomeTabellaDaSist);
        SqlQueryUpdate.UpdateSQL.Add('set ' +
                                     CstNomeColonnaDaSist +
                                     ' = ' +
                                     MettiVirgolette(CstValCampoNew, tvSemp));
        SqlQueryUpdate.UpdateSQL.Add('where ' + CstNomeColonnaDaSist + ' = ' +
                                     MettiVirgolette(CstValCampoOld, tvSemp));
        //Scrivo la modifica
        //SqlQueryUpdate.UpdateSQL.SaveToFile(WinTemp + 'Mario.txt');
        SqlQueryUpdate.Open;
          SqlQueryUpdate.Edit;
          SqlQueryUpdate.Post;
          SqlQueryUpdate.ApplyUpdates;
        SqlQueryUpdate.Close;

        //Ora che ho finito di leggere il DB, lo posso aggiornare (COMMIT)
        SQLTransaction1.CommitRetaining;

Ricordo che all'epoca le avevo trovate tramite una ricerca, e non so se sono o meno equivalenti a quelle che usi tu.

Ciao, Mario

bonmario

  • Hero Member
  • *****
  • Post: 1300
  • Karma: +10/-1
Re:Aiuto, perdo record
« Risposta #7 il: Agosto 09, 2022, 08:13:47 am »
... dimenticavo ... Se l'istruzione di write/update fallisce, dovrebbe segnalare un errore a video.
Se le persone che dicono di avere inserito il record che poi non si trova non hanno visto questo messaggio, può essere che il problema sia da un'altra parte?
Ad esempio, magari il record viene inserito correttamente, ma poi c'è qualcosa che lo va a cancellare in un secondo momento ...

Ciao, Mario

tito_livio

  • Full Member
  • ***
  • Post: 146
  • Karma: +3/-0
Re:Aiuto, perdo record
« Risposta #8 il: Agosto 09, 2022, 08:57:18 am »
Buongiorno,
per DragoRosso:
Potrebbe essere come dici tu a proposito delle transazioni contemporanee. Ho scoperto che nel mio programma in effetti c'è la possibilità che ci siano due transazioni contemporanee, generate dallo stesso client, su due tabelle diverse, una delle quali è quella che mi crea problemi. Ho escluso la possibilità che questo si verifichi e sto tenenendo il tutto sotto controllo.
Si, uso lab_anno, che è una TMySql50Connection, per la commit, mentre tesiti che è una TSqlQuery per l'append dei nuovi record. Secondo te dovrei fare diversamente?
Per Bonmario:
a parte il fatto che nel tuo codice tu aggiorni mentre io aggiungo, il salvataggio è quasi lo stesso. Le uniche cose che tu scrivi in più sono:
Codice: [Seleziona]
SqlQueryUpdate.Edit;
SqlQueryUpdate.Post;
secondo me Edit è inutile mentre Post ricordo che mi dava problemi ma non mi ricordo quali.
Purtroppo nessuno mi riferisce di messaggi d'errore a video. E nessun umano va a cancellare i record, me ne accorgo da alcune altre tabelle.
Sembra proprio un salvataggio non andato a buon fine. Grazie per la risposta.


DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Aiuto, perdo record
« Risposta #9 il: Agosto 09, 2022, 10:19:24 am »
Si, uso lab_anno, che è una TMySql50Connection, per la commit, mentre tesiti che è una TSqlQuery per l'append dei nuovi record. Secondo te dovrei fare diversamente?

No, è che non sapevo cosa era lab_anno, e quindi magari era una svista nel codice (a me è successo più di qualche volta  ;) ).

Ciao
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Aiuto, perdo record
« Risposta #10 il: Agosto 09, 2022, 03:42:12 pm »
Una riflessione, io che provengo storicamente dalla situazione dove i database erano banalmente un insieme di record di dati accodati uno dietro l'altro (l'ISAM originale), dove le transaction erano più che altro delle idee "transitorie" ( ;D ), ho sempre usato i database in un due modi:

- classico andando a scrivere direttamente in ogni singola tabella (salvo l'ausilio relativamente moderno delle master / detail) usando la sequenza INSERT (O EDIT), IMMISSIONE DATI NEI CAMPI, POST;

- usando le QUERY SQL, dove la query fà ovviamente tutto (al limite si lanciano più query).

Il Commit, ossia la chiusura di una transazione l'ho usata pochissime volte e solo ed esclusivamente dove il cliente pretendeva la certificazione (con tanto di log) delle transazioni appunto.

Questo non tanto perchè la tecnologia delle transaction non sia affidabile, ma fino a poco tempo fà c'erano molti limiti al suo utilizzo, e tra l'altro limiti il cui "sforamento" provocava un emerito NULLA, nessuna segnalazione, nessun errore, niente. Certamente per colpa principale dei componenti, delle dll client o di altro, però tant'era.

Ma appunto dal mio provenire dall'ISAM, e non ho mai cambiato atteggiamento, ho sempre ed esclusivamente SCRITTO nel database attraverso UNA E UNA SOLA FUNZIONE, NORMALMENTE TRAMITE UN THREAD, serializzata da un semaforo in modo tale che il programma eseguisse le attività di scrittura da un solo LUOGO e in un solo istante. Per razionalizzare il codice poi o gestito più funzioni MA SEMPRE SERIALIZZATE con lo stesso semaforo. Ciò mi ha consentito di non avere mai alcun problema, con alcun database sia esso basato su Server che su FILE.

Fate attenzione quando lavorate con i database, ma non solo, che con i moderni processori la gestione del Threading deve essere effettuata da "manuale" (nel senso che SI DEVONO ESEGUIRE ALLA LETTERA LE LINEE GUIDA): dimenticatevi i tempi mascherati o altro .... non funzionano. Provato sulla propria pelle.

Ciao
 
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

SB

  • Scrittore
  • Sr. Member
  • *****
  • Post: 283
  • Karma: +1/-0
Re:Aiuto, perdo record
« Risposta #11 il: Agosto 14, 2022, 10:08:57 am »
Io suderei freddo a perdere un singolo record. Perderne migliaia... :o

Dubito che il problema stia in MySQL. Dubito che stia nelle librerie usate perchè l'operazione sembra troppo banale.

Non è che per caso imposti dei valori non validi nel record da aggiungere e l'operazione fallisce?
Ad esempio un valore non unico in un campo indicizzato unico, o un valore nullo in un campo non nullo?
E non te ne accorgi perchè non controlli che l'operazione sia andata a buon fine, ad esempio con RowsAffected?


Buongiorno a tutti,
in un nuovo progetto, ho un database Mysql con diverse tabelle, di tipo MyIsam, alle quali accedono alcuni client, anche una decina, con dei mie programmi.
Il problema è che, circa l'uno percento dei record aggiunti, non vengono poi ritrovati.
Essendo che ci sono tabelle anche con 900.000 record, il problema diventa frequente.
I programmi girano sotto Windows 64 bit e 32 bit, sono compilati per 32 bit con la versione 2.0.6.
Uso i componenti nativi, non quelli Zeos, e il codice che uso per salvare segue questo semplice schema:

Codice: [Seleziona]
          fdm.tesiti.AppendRecord([....]);
          fdm.tesiti.applyupdates(8);
          fdm.lab_anno.transaction.commitretaining;
          fdm.tesiti.Close;
          fdm.tesiti.Open;

L'argomento 8 della funzione applyupdates è stato inserito per cercare di correggere il problema ma non risolve.
Grazie in anticipo.

tito_livio

  • Full Member
  • ***
  • Post: 146
  • Karma: +3/-0
Re:Aiuto, perdo record
« Risposta #12 il: Agosto 14, 2022, 03:03:50 pm »

Ma appunto dal mio provenire dall'ISAM, e non ho mai cambiato atteggiamento, ho sempre ed esclusivamente SCRITTO nel database attraverso UNA E UNA SOLA FUNZIONE, NORMALMENTE TRAMITE UN THREAD, serializzata da un semaforo in modo tale che il programma eseguisse le attività di scrittura da un solo LUOGO e in un solo istante.
 

Ma tu intendi che per ogni client scrivi sempre con un solo thread su di una sola tabella alla volta oppure serializzi la scrittura ad una tabella (o a tutto il database) per tutti i client in rete?

Io suderei freddo a perdere un singolo record. Perderne migliaia... :o

Infatti, ho rimediato al problema ma in una maniera complicata che non mi piace.

Non è che per caso imposti dei valori non validi nel record da aggiungere e l'operazione fallisce?
Ad esempio un valore non unico in un campo indicizzato unico, o un valore nullo in un campo non nullo?

Non penso che sia questo perché ripetendo la stessa scrittura, con gli stessi dati, non succede.
In pratica una volta su tante la scrittura non va a buon fine, anche se scrivo sempre le stesse cose.

E non te ne accorgi perchè non controlli che l'operazione sia andata a buon fine, ad esempio con RowsAffected?

Questo si, lo proverò, grazie per la risposta.

SB

  • Scrittore
  • Sr. Member
  • *****
  • Post: 283
  • Karma: +1/-0
Re:Aiuto, perdo record
« Risposta #13 il: Agosto 14, 2022, 03:42:45 pm »
Non è che per caso imposti dei valori non validi nel record da aggiungere e l'operazione fallisce?
Ad esempio un valore non unico in un campo indicizzato unico, o un valore nullo in un campo non nullo?

Non penso che sia questo perché ripetendo la stessa scrittura, con gli stessi dati, non succede.
In pratica una volta su tante la scrittura non va a buon fine, anche se scrivo sempre le stesse cose.

Dunque i valori che inserisci sarebbero validi
A me sembra un errore di valori duplicati su un campo indicizzato.
Ad esempio, per qualche motivo non hai usato i campi chiave autonumeranti e i client generano autonomamente delle chiavi per identificare i record, ma non hai un meccanismo che garantisca che queste chiavi siano effettivamente uniche nella tabella. Il meccanismo che usi funziona bene normalmente (al 99%) ma ogni tanto saltano fuori chiavi identiche su client diversi e l'append fallisce

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1266
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Aiuto, perdo record
« Risposta #14 il: Agosto 14, 2022, 05:58:30 pm »
Ma appunto dal mio provenire dall'ISAM, e non ho mai cambiato atteggiamento, ho sempre ed esclusivamente SCRITTO nel database attraverso UNA E UNA SOLA FUNZIONE, NORMALMENTE TRAMITE UN THREAD, serializzata da un semaforo in modo tale che il programma eseguisse le attività di scrittura da un solo LUOGO e in un solo istante.

Ma tu intendi che per ogni client scrivi sempre con un solo thread su di una sola tabella alla volta oppure serializzi la scrittura ad una tabella (o a tutto il database) per tutti i client in rete?


Intendevo per operazioni effettuate da un singolo client direttamente dall'applicativo. Lasciando per un attimo perdere i client su rete, già con un solo client puoi avere problemi se instauri più transazioni (ossia scritture multiple) contemporanee da più Thread: ovvio che dipende dal motore che scegli. Se usi Oracle o Microsoft con le versioni enterprise dei prodotti è certo che puoi fare più o meno quello che vuoi senza prestare bada ai Thread, ai client o ad altri dettagli.

Poi, pensando ad un sistema multiclient, le cose si fanno più complesse e occorre molto spesso migrare su database più performanti e sicuri.

Ciao
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

 

Recenti

How To

Utenti
  • Utenti in totale: 785
  • Latest: gmax
Stats
  • Post in totale: 18769
  • Topic in totale: 2232
  • Online Today: 95
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 73
Total: 73

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.