Database in rete

di il
16 risposte

Database in rete

Ciao a tutti,

Avrei bisogno di un'informazione relativa a come lavorare in rete con la stessa istanza del database.

Ho un database chiamato “fornitori” e l'entity data model per interagire con esso, con una tabella chiamata “nominativi”.

All'avvio del programma mi apro l'istanza del database “FornitoriEntities fornit=new FornitoriEntities()”

Fin qui.. tutto normale…

Il programma lavora in rete, quindi ho creato due macchine virtuali e vi ho installato il programma con la corretta connectionstring (il programma funziona su entrambi le macchine), l'unico problema è che se dalla macchina1 aggiungo un campo nella tabella o cambio il valore di un campo il valore viene registrato correttamente nel database tramite il medoto SaveChanges ma aprendo il software sulla macchina2 non mi aggiorna il valore ma vede sempre quello vecchio, tranne se esco e rientro come se si aprisse di nuovo l'istanza da capo e siaggiornasse.

Come posso fare per vedere automaticamente i dati inseriti sulla macchina1 anche sulla macchina2 senza uscire e rientrare?

Spero di essere stati chiaro e grazie a chi vorrò dedicarmi un aiuto.

16 Risposte

  • Re: Database in rete

    Non indichi QUALE DBMS stai usando! 

    Access? , SQL Server? Altro? 

  • Re: Database in rete

    Chiedo scusa… sto usando SQL Server 2019 Express

  • Re: Database in rete

    14/07/2023 - migliorabile ha scritto:


    Chiedo scusa… sto usando SQL Server 2019 Express

  • Re: Database in rete

    L'errore piu' probabile e' che non fai il COMMIT delle modifiche, e non CHIUDI  la connessione.

    Il processo B NON VEDRA' le modifiche del processo A fino a che A non fa il. COMMIT. 

    Questa e' una delle proprietà ACID (che non vuol dire che si e' fatto di acido/LSD! ) di un DBMS.

    Piu' in generale, devi approfondire il concetto. di TRANSAZIONE:

    una TRANSAZIONE va aperta (begin) , quindi chiusa con COMMIT o ROLLBACK.

    Dentro la transazione fai quello che vuoi. Le modifiche saranno visibili SOLO dopo il COMMIT. Ma questa e' SOLO LA PRIMA PARTE della storia.

    Durante la transazione, sono visibili SOLO le modifiche di transazioni GIA' CHIUSE al momento della begin.

  • Re: Database in rete

    All'avvio del programma mi apro l'istanza con FornitoriEntities fornit=new FornitoriEntities() e poi quando devo salvare i valori nelle varie select, utilzzo il metodo fonit.SaveChanges().

    Se ad esempio sulla macchina1 nel campo cognome inserisco “rossi” tramite sql server management studio ho visto che effettivamente mi inserisce il valore “rossi” nel database, ma se sulla macchina2 mi faccio comparire un messaggio mi porta sempre il valore vecchio anzichè rossi, se invece esco e rientro allora mi porta correttamente “rossi”.

    Scusami, come posso fare per fare il commit ochiudere la connessione?

    Premetto che non ho utilizzato stored procedure ma faccio tutto tramite entity data model.

    Grazie ancora.

  • Re: Database in rete

    Per spiergami meglio… 

    DALLA MACCHINA1

    All'avvio del programma mi apro l'istanza con DBFornitoriEntities  fonitori = new DBFornitoriEntities ();

    // Assegno il valore al campo della tabella:

    fornitori.cognome="PIPPO";

    fornitori.savechanges();

    Il valore viene correttamente salvato.

    Se però dalla MACCHINA2 mi recupero il valore di quel campo, non mi riporta “PIPPO” ma il vecchio valore (come se non leggesse il db).

    Se invece (sempre dalla macchina2) esco e rientro, quindi si fa di nuovo l'apertura dell'istanza, allora mi prende il valore corretto.

    Vorrei fare il modo da prendermi il valore corretto da macchina2 senza dover uscire e rientrare dal software.

    Non sapere come fare il commit o chiusura della connessione.

  • Re: Database in rete

    Q

    14/07/2023 - ducas ha scritto:


    Per spiergami meglio… 

    Il programma lavora in rete su due macchine virtuali (macchina1 e macchina2) 

    DALLA MACCHINA1

    All'avvio del programma mi apro l'istanza con DBFornitoriEntities  fonitori = new DBFornitoriEntities ();

    // Assegno il valore al campo della tabella:

    fornitori.cognome="PIPPO";

    fornitori.savechanges();

    Il valore viene correttamente salvato.

    Se però dalla MACCHINA2 mi recupero il valore di quel campo, non mi riporta “PIPPO” ma il vecchio valore (come se non leggesse il db).

    Se invece (sempre dalla macchina2) esco e rientro, quindi si fa di nuovo l'apertura dell'istanza, allora mi prende il valore corretto.

    Vorrei fare il modo da prendermi il valore corretto da macchina2 senza dover uscire e rientrare dal software.

    Qualcuno sa come potermi aiutare per favore?

  • Re: Database in rete

    Uhm… secondo me tu sei convinto che quando visualizzi un record o una tabella la tua macchina è collegata come una lampadina alla rete elettrica…

    Quando apri una vista tabella il server ti invia i dati e restano quelli finché non riceve un'altra richiesta.

    Una analogia per capire meglio….

    Apri un file di testo o un foglio elettronico il programma prende il file e te ne fa vedere una copia. Fai tutte le modifiche che vuoi ma se non salvi perdi le modifiche. Cosa avviene? Quando salvi il programma manda il nuovo file e lo sostituisce.

    Se pippo e pluto lavorano sullo stesso file, pippo cancella tutto e pluto ha ancora il suo bel file integri, se salva il file diventa quello di pluto e pippo pensa che non ha cancellato niente…

    Il db fa lo stesso, infatti quando posti il record si avvia una istanza per apportare le modifiche.

    Devi impedire la modifica del record se un utente sta lavorando con lo stesso record. Pensa se 1000 utenti dovessero restare appesi al server… il servere manda i dati a chi ne fa richiesta e li salva quando gli viene detto di salvarli. Il concetto è semplice… anche quando scrivi il 3d non vediamo il testo finché non fai invia..

  • Re: Database in rete

    14/07/2023 - sihsandrea ha scritto:


    Uhm… secondo me tu sei convinto che quando visualizzi un record o una tabella la tua macchina è collegata come una lampadina alla rete elettrica…

    Quando apri una vista tabella il server ti invia i dati e restano quelli finché non riceve un'altra richiesta.

    Una analogia per capire meglio….

    Apri un file di testo o un foglio elettronico il programma prende il file e te ne fa vedere una copia. Fai tutte le modifiche che vuoi ma se non salvi perdi le modifiche. Cosa avviene? Quando salvi il programma manda il nuovo file e lo sostituisce.

    Se pippo e pluto lavorano sullo stesso file, pippo cancella tutto e pluto ha ancora il suo bel file integri, se salva il file diventa quello di pluto e pippo pensa che non ha cancellato niente…

    Il db fa lo stesso, infatti quando posti il record si avvia una istanza per apportare le modifiche.

    Devi impedire la modifica del record se un utente sta lavorando con lo stesso record. Pensa se 1000 utenti dovessero restare appesi al server… il servere manda i dati a chi ne fa richiesta e li salva quando gli viene detto di salvarli. Il concetto è semplice… anche quando scrivi il 3d non vediamo il testo finché non fai invia..

    Ti ringrazio per la risposta, sei stato molto chiaro ed ho capito cosa intendi. Ma sicuramente mi sono espresso male io e chiedo scusa anche di questo.

    Il mio problema non è che si perdono i dati, cioè, ho un software che lavora in rete (installato su due macchine virtuali pe test) e comunicano correttamente, il problema è che non vedo in maniera sincronizzata o istantanea i dati.

    Esempio: se sulla macchina server valorizzo un campo di una tabella assegnandogli un valore e poi lo salvo (nel database vedo che è stato salvato correttamente e sulla macchina dove ho fatto l'operazione mi si aggiorna) ma non lo vedo in maniera automatica anche sull'altra macchina, ma per vederlo devo uscire e rientrare dal software. E non riesco a capire come poter fare per visualizzare i dati in maniera “diciamo sincronizzata” anche sull'altra macchina. :( spero di essermi spiegato un po meglio.

  • Re: Database in rete

    14/07/2023 - ducas ha scritto:


    14/07/2023 - sihsandrea ha scritto:


    Uhm… secondo me tu sei convinto che quando visualizzi un record o una tabella la tua macchina è collegata come una lampadina alla rete elettrica…

    Quando apri una vista tabella il server ti invia i dati e restano quelli finché non riceve un'altra richiesta.

    Una analogia per capire meglio….

    Apri un file di testo o un foglio elettronico il programma prende il file e te ne fa vedere una copia. Fai tutte le modifiche che vuoi ma se non salvi perdi le modifiche. Cosa avviene? Quando salvi il programma manda il nuovo file e lo sostituisce.

    Se pippo e pluto lavorano sullo stesso file, pippo cancella tutto e pluto ha ancora il suo bel file integri, se salva il file diventa quello di pluto e pippo pensa che non ha cancellato niente…

    Il db fa lo stesso, infatti quando posti il record si avvia una istanza per apportare le modifiche.

    Devi impedire la modifica del record se un utente sta lavorando con lo stesso record. Pensa se 1000 utenti dovessero restare appesi al server… il servere manda i dati a chi ne fa richiesta e li salva quando gli viene detto di salvarli. Il concetto è semplice… anche quando scrivi il 3d non vediamo il testo finché non fai invia..

    Ovviamente il sofftware all'avvio si crea una nuova istanza del database, quindi lo lancio dalla macchina1 e si crea l'istanza, avviandolo anche sulla macchina2 anche li si crea l'istanza e non so se questo potrebbe creare probemi lavorando su istanze diverse , essendo instanze diverse forse è questo che crea il problema non saprei come uscirne :(

  • Re: Database in rete

    Forse non hai letto bene l'esempio del file di testo o foglio di calcolo… apri due volte lo stesso file e modificane uno e lo salvi, poi vedi se l'altro aperto è cambiato… e sei sulla stessa macchina.

  • Re: Database in rete

    @ducas, direi che ti sei “attestato” sulle tue posizioni e chiedi una soluzione “non implementabile”. 

    NON E' IL DBMS che deve fare quello che vuoi tu, se TU che devi usare il DBMS come VUOLE LUI.

    Chi lo ha progettato (visto che il concetto di DBMS ha 60 anni) ha gia' previsto TUTTI i casi CORRETTI & POSSIBILI di utilizzo.

  • Re: Database in rete

    Ciao, vorrei dare anch'io il mio contributo:

    @ducas sei stato chiarissimo: sulla virtuale macchina1 hai installato SQL Server 2019 Express con il tuo database, al quale accedi in remoto anche dalla macchina2, anch'essa virtuale, e hai configurato perfettamente l'accesso in remoto a SQL Server. Sulle due macchine gira lo stesso tuo software.

    Tralasciamo per il momento il fatto (importantissimo) che non hai spiegato come hai gestito la Concorrenza Ottimistica, visto che in caso di lettura-scrittura simultanea da parte di due utenti, tutti i nodi verrebbero al pettine, i dati non sarebbero congrui e le eccezioni non mancherebbero.

    Ora, stai sicuro che con Entity Framework, quando leggi un “record”, lo modifichi e lo riscrivi sul database, prima di fornit.SaveChanges(), per persitere i dati sul database devi settare su Modified lo State della tua Entity altrimenti non vedi la modifica neanche sulla macchina1, perchè essa non viene scritta.

    In pratica, supponiamo che tu voglia cambiare il cognome di un fornitore:

    1) leggi il “record fornitore" dal tuo Context che hai chiamato fornit mettendolo ad esempio nella Entity “fornitoreModificato

    2) cambi il cognome con: “Rossi”;

    3) setti lo stato della Entity su Modified;

    4) salvi i dati sul database.

    In codice:

    fornitoreModificato.Cognome = "Rossi";
    fornit.Entry(fornitoreModificato).State = EntityState.Modified;
    fornit.SaveChanges();

    Con il SaveChanges() vedrai la modifica anche sulla macchina2.

    Se invece, tu semplicemente aggiungi un nuovo fornitore (cioè aggiungi un nuovo oggetto al contesto), non hai bisogno di cambiare lo stato di questa nuova entity perchè ci pensa automaticamente Entity Framework e non hai bisogno neanche di preoccuparti della Concorrenza Ottimistica, di cui dovremmo invece anche parlare… (colonne RowVersion… tipi Timestamp… ConcurrencyCheck… ecc…)

    Buon divertimento.

  • Re: Database in rete

    Ciao

    Mi unisco al discorso di Fabio Caruso e credo il problema sia nell'uso improprio di EntityFramework.

    Credo però il problema risieda più nella lettura che nella scrittura, perchè affermi che riavviando il processo nella macchina B il dato lo leggi correttamente (per cui i dati sul DB sono stati scritti e committati).

    Non so se lo sapevi, però EntityFramework cerca di ottimizare le letture. Pertanto, se ha portato in memoria una tabella (DbSet di entità), poi non la legge più dal database ma ritorna quella che ha in memoria.

    Che sappia io ci sono due alternative:

    1. Attivi un'opzione in fase di configurazione di EntityFramework per obbligare a leggere sempre dal DB (non ricordo quale sia)
    2. Forzi di tanto in tanto il db a fare un Reload del tuo DbSet (ci dovrebbe proprio essere la funzione “Reload”, tipo DbContext.Fornitori.Reload() )
Devi accedere o registrarti per scrivere nel forum
16 risposte