Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [Delphi] Interbase e la rete : "Black hole"

    Ciao a tutti!
    Prima di postare questo topic ho letto su Internet molti argomenti
    inerenti la gestione di un database(Tipo Interbase) centralizzato, quindi in ambito di una struttura di rete (LAN).

    Ho capito che bisogna aggiungere un trigger ad ogni tabella che permetta di "alzare" un flag per ogni evento (BEFORE UPDATE, AFTER INSERT, ...) che si scatena.

    Ed ancora, per quanto riguarda la parte in Delphi, aggiungere il componente IBEvents per controllare i flag sopra citati.

    Testando l'applicazione su due computer, naturalmente collegati in rete, il componente IBEvent mostra il messaggio inerente l'azione avvenuta solo quando si chiude il programma che ha generato l'azione.

    Esempio:
    Client A , modifica il record di una tabella
    Cliente B, non riceve nessun messaggio

    solo quando termino il lavoro sul Client A, allora il client B riceve il flag per l'azione avvenuta.

    In teoria e in pratica, non dovrei terminare una sessione di lavoro per fare in modo che gli altri client si accorgano delle modifiche che sono state apportate.

    Come si può risolvere questo problema ?

    Grazie
    Piccaweb

  2. #2
    solitamente questo succede quando non avviene l'update delle modifiche che tu con il client A effettui sul record. Infatti interbase genera l'update quando tu, chiudendo l'applicazione, gli dici "ottimisticamente" ho finito.

    Controlla che le commit siano impostate per bene.

    E fammi sapere
    Il dubbio non è piacevole, ma la certezza è ridicola. Solo gli imbecilli son sicuri di ciò che dicono.

  3. #3
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,295
    Le impostazioni di isolamento delle transazioni devono essere impostate su read committed per poter leggere tutti i dati che sono stati "confermati" dagli operatori attraverso la Commit o CommitRetaining, metodo che può essere richiamato dal componente IBTransaction.

    Non capisco perchè fai uso di trigger ed eventi per costruire dei "blocchi"...il vantaggio di InterBase è proprio quello di consentire agevolmente a più utenti di lavorare assieme.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  4. #4
    Il problema non é nelle transizioni, poiché i parametri sono settati correttamente; ma si tratta di come gestire gli aggiornamenti sui client!

    Penso che di argomenti di questo tipo ce ne siano una marea su internet ma per quato riguarda Interbase in particolare, ne ho trovati pochi e nei quali si consigliava di aggiungere un campo ad ogni tabella nel quale memorizzare il nome dell'utente che sta accedendo al record.
    Oppure un'altra soluzione é quelle dei trigger o delle stored procedure.

    In realtà, l'azione di lock viene eseguita su ogni client quando tento di accedere ad un record di una tabella e mi viene mostrato un errore edl tipo :"Block record".
    Questo messaggio scompare solo quando l'utente che ha avuto accesso epr primo al record termina la sua sessione di lavoro, dove per sessione di lavoro intendo la chiusura del programma.

    In teoria, vorrei una situazione più semplice da gestire, e sot provando diverse situazioni di lavoro per vedere come si comporta Interbase.

    Esiste un modo semplice ma robusto per fare il refresh, oppure per mantere l'integrità dei dati, di un database condiviso in rete ?


  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,295
    Non riesco a comprendere bene la problematica... :master:

    InterBase è un database server progettato appositamente per consentire il collegamento e l'accesso simultaneo di più utenti alla base dati, con la possibilità di apportare modifiche (inserimenti, aggiornamenti e cancellazioni) inglobale all'interno di transazioni per poter mantenere sempre "valida" la struttura del database.

    Non si parla quindi mai di lock o di cose simili: tutti gli utenti hanno in ogni momento la possibilità di visualizzare i dati che hanno subito la "Commit" da parte di altri utenti...in definitiva, una versione valida del database con la quale lavorare.

    L'integrità dei dati è sempre mantenuta e garantita dal database server.

    Se il problema è ottenere costantemente la "versione aggiornata" dei dati presenti sul server, non c'è altro rimedio che eseguire la query di origine, quella che popola i controlli con i quali l'utente deve lavorare.

    E' possibile agire sui dati anche con una modalità "disconnessa", usando ad esempio il componente TClientDataSet, che ottiene dal server i dati e li memorizza all'interno di una cache modificabile per consentire all'utente di apportare i cambiamenti desiderati, generando poi in sequenza, in un secondo momento, le istruzioni SQL per aggiornare la base dati.

    In definitiva, InterBase non contempla il concetto di lock dei record, a meno che non lo si realizzi con un qualche stratagemma (ad esempio, uso di una tabella apposita e controllo dello stato di blocco attraverso trigger e stored procedure, nonchè eccezioni).

    Non vedo comunque perchè usare un concetto di lock invece di consentire a tutti gli utenti di lavorare contemporaneamente.

    La gestione delle transazioni previene comunque l'ingresso del database in uno stato non consistente, con dati sfalsati o incongruenti.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    Se il problema è ottenere costantemente la "versione aggiornata" dei dati presenti sul server, non c'è altro rimedio che eseguire la query di origine, quella che popola i controlli con i quali l'utente deve lavorare.
    E' prorprio questo il problema.
    Quello che mi accade é che se aggiungo un nuovo record in una tabella "pippo" sul client A, rieseguendo una query di visualizzazione dei dati di "pippo" sul client B, il risultato rimane invariato, ovvero non mi viene mostrato l'ultimo record inserito.

    E' in questo punto che riletto in continuazione.

  7. #7
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,295
    Le possibilità sono solo due:
    [list=a][*]sul primo client non viene richiamata la CommitRetaining del componente IBTransaction per effettuare la conferma (commit) della transazione dopo l'operazione di Post del record;[*]le impostazioni di visibilità sul secondo client, quindi in tutti i client, impediscono la lettura dei valori che hanno già subito la "commit".[/list=a]
    Le soluzioni sono:
    nel primo caso, aggiungere la chiamata al metodo CommitRetaining sul componente IBTransaction, magari nell'evento OnAfterPost del componente utilizzato per l'accesso e la modifica dei dati;
    nel secondo caso, richiamare il Transaction Editor facendo clic con il pulsante destro sul componente IBTransaction e impostare le Transaction Properties su Read Committed, affinchè i client possano vedere le modifiche degli altri utenti che hanno subito la Commit.

    E' ovvio che quando si parla di "visibilità" ci si riferisce al fatto di avere a disposizione una base dati che include le modifiche apportate da altri utenti e la possibilità di visualizzarle...ma ciò deve avvenire esplicitamente chiudendo e riaprendo la query usata per il reperimento dei dati o il componente usato comunque per l'accesso (IBTable, IBQuery, ecc.).

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  8. #8
    scusate l'intromissione ... vi volevo fare una domanda
    io dato che avevo avuto lo stesso problema e per mancanza di documentazione ci stavo per perdere la testa, ho risolto il problema in altro modo utilizzando il BDE ho creato un alias INTRBASE e con il database e le tabelle BDE sono riuscito a far funzionareil programma in rete , ora la domanda è la seguente :

    la soluzione che ho trovato è stabile, o no? può creare dei problemi?
    fino ad adesso funge tutto !!!

    Ho fatto una mega C***ata ??????

    riscritto il codice e compilato sono circa 392000 righe di codice ....
    devo ricambiare tutto o posso lasciare tutto così???

    grazie

  9. #9
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,295
    Il BDE è una tecnologia di accesso ai dati come un'altra.

    Per funzionare in rete, basta accedere ad un database gestito da un server InterBase installato su una macchina diversa da quella in cui risiede l'applicazione.

    Che poi si indichi il percorso del database e si utilizzino i componenti IBX (InterBase Express) oppure si usi il BDE, poco conta, sebbene ricordo che il BDE dovrebbe avere - se non diversamente specificato - una gestione implicita delle transazioni: ad ogni operazione corrisponde l'avvio di una transizione e la conferma (Commit) automatica, quindi è possibile giungere ad una situazione non coerente del database.

    Ad esempio, se una procedura come il prelievo di merce da un magazzino per la creazione di una bolla deve essere vista in modo atomico, non usando la transazione si può arrivare all'impossibilità di concludere una bolla pur avendo già rimosso il record dell'articolo (e confermato), mentre tale operazione deve avvenire con successo nella sua interezza, o fallire nella sua interezza.

    Comunque, risulta difficile dal numero di righe capire se ci sono dei problemi...dipende dal tipo di applicazione, dal modo con cui sono state progettate le operazioni; se nessuno presenta dei problemi, non apportare modifiche.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  10. #10
    Ricontrollando il codice, in effetti non era impostato a Read Committed la proprietà del componente IBTransaction.
    Infatti, facendo l'aggiornamento di una query, mi appaiono i nuovi risultati dall'interrogazione.

    Ora, sto riflettendo quale sia il modo migliore per avvisare un Client quando sta cercando di "entrare" in un record già aperto da una altro utente.
    Anche se come dice giustamente Alka:
    Non vedo comunque perchè usare un concetto di lock invece di consentire a tutti gli utenti di lavorare contemporaneamente.
    quello che vorrei realizzare é solo un semplice messaggio di avviso e non un blocco sistematico del record da parte dell'utente che ha avuto accesso per primo al record.
    Il messaggio sarebbe tipo Warning :"Attenzione: un altro utente é ... Vuoi proseguire ?"

    Potrebbe essere una buona idea ?


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.