Anteprima risultati calcoli nel FrontEnd
Quote from Miky on 25/11/2020, 10:22Ciao
Nel progetto a cui sto lavorando, mi appoggio a SQLServer.
Sul DB eseguo un sacco di calcoli complessi con livelli di annidamento profondi.
Visto che i calcoli vengono eseguiti da Query, StoredProcedure e Funzioni sul DB, con questo assetto, quando un utente modifica dei valori, dovrei prima salvare il dato modificato per poi vederne il risultato.
Quello che vorrei e' che lato FrontEnd venga subito rappresentato il risultato ad ogni modifica.
Se l'utente e' soddisfatto puo' quindi procedere al salvataggio delle modifiche.
E' impensabile che possa ricostruire tutto il modello di calcolo lato FE.
C'e' qualche soluzione a questo quesito?
Miky
Ciao
Nel progetto a cui sto lavorando, mi appoggio a SQLServer.
Sul DB eseguo un sacco di calcoli complessi con livelli di annidamento profondi.
Visto che i calcoli vengono eseguiti da Query, StoredProcedure e Funzioni sul DB, con questo assetto, quando un utente modifica dei valori, dovrei prima salvare il dato modificato per poi vederne il risultato.
Quello che vorrei e' che lato FrontEnd venga subito rappresentato il risultato ad ogni modifica.
Se l'utente e' soddisfatto puo' quindi procedere al salvataggio delle modifiche.
E' impensabile che possa ricostruire tutto il modello di calcolo lato FE.
C'e' qualche soluzione a questo quesito?
Miky
Quote from sabrina_c on 29/11/2020, 17:32Temo ci sia ben poco che tu possa fare per risolvere il problema. Solitamnete il DB conserva i dati, non la Business Logic. Avendo tu scelto di gestire la Business Logic dentro al DB salvo creare il nuovo record marcandolo con un marcatore che ti permetta di riconoscerlo come "non ancora approvato" per poterlo eliminare se l'utente non lo conferma, non hai molto altro da fare.
Se hai un record o più record correlati con l'azione che deve essere confermata, puoi utilizzare un campo dove mettere un codice che associ ai record delle varie tabelle appartenenti ad un "batch" in modo che siano facilmente riconoscibili, filtrabili e quindi eliminabili se l'operazione viene annullata.
Altrimenti dovresti inserire tutta la logica nell'applicazione e scrivere sul DB solo il risultato se confermato. Ma hai già detto tu che non è una strada praticabile.
Saluti
Temo ci sia ben poco che tu possa fare per risolvere il problema. Solitamnete il DB conserva i dati, non la Business Logic. Avendo tu scelto di gestire la Business Logic dentro al DB salvo creare il nuovo record marcandolo con un marcatore che ti permetta di riconoscerlo come "non ancora approvato" per poterlo eliminare se l'utente non lo conferma, non hai molto altro da fare.
Se hai un record o più record correlati con l'azione che deve essere confermata, puoi utilizzare un campo dove mettere un codice che associ ai record delle varie tabelle appartenenti ad un "batch" in modo che siano facilmente riconoscibili, filtrabili e quindi eliminabili se l'operazione viene annullata.
Altrimenti dovresti inserire tutta la logica nell'applicazione e scrivere sul DB solo il risultato se confermato. Ma hai già detto tu che non è una strada praticabile.
Saluti
Quote from Miky on 01/12/2020, 15:51Grazie Sabrina
Da qualche parte però ho visto che si potrebbe tentare con una transaction e poi eseguire il rollbak tipo:
BEGIN TRAN UPDATE myTable SET field = 123; SELECT * FROM myView ; ROLLBACK;
Non mi convince molto come soluzione anche se credo sia l'unico modo, cosa ne pensi? Mai testata?
Grazie Sabrina
Da qualche parte però ho visto che si potrebbe tentare con una transaction e poi eseguire il rollbak tipo:
BEGIN TRAN
UPDATE myTable SET field = 123;
SELECT * FROM myView ;
ROLLBACK;
Non mi convince molto come soluzione anche se credo sia l'unico modo, cosa ne pensi? Mai testata?
Quote from sabrina_c on 07/12/2020, 19:25Anche qui rispondo in ritardissimo...
Rileggere dei valori modificati mentre una transazione è in corso significherebbe modificare il comportamento delle operazioni sul Database attivando la modalità Read_Uncommitted, sinceramente non ho idea di come si possa fare perché non mi è mai passato per la mente di farlo, ma se esiste sicuramente qualcuno la usa, perciò puoi provare.
La documentazione ufficiale di Microsoft relativa al Transaction Isolation Level e come si modifica
Un articolo interessante sulle transazioni e i livelli di transazione.
Se non cambi l'Isolation Level, la lettura attenderà il commit/rollback per darti i risultati quindi se non calibri correttamente le funzionalità rischi un DeadLock sul database. Ovviamente se sei in multiutenza e usi il livello di isolamento Read_uncommitted i tuoi utenti possono ricevere dati inconsistenti e potrebbero generare ulteriori inconsistenze su altri dati.
Una tecnica che un collega ha usato per una operazione dove perdere il dato in corso a causa di un problema dell'utente era possibile ma non auspicabile è stata di inventarsi dei record di tipo "Temporaneo" dove crea il dato transazionale non ancora confermato, scrivendolo sul database, poi quando l'utente consolida il dato viene trasformato in dato definitivo. Ma in questo caso si trattava di una singola tabella di cui duplicava un numero di righe su cui l'utente stava lavorando. Ed era molto semplice buttarle se restavano appese o farle rivedere all'utente. Inoltre venivano utilizzate come mezzo di blocco per evitare che più utenti modificassero lo stesso oggetto, se nel tuo caso ci sono modifiche su varie tabelle potrebbe essere difficile gestirlo con qualcosa di questo genere.
Saluti
Anche qui rispondo in ritardissimo...
Rileggere dei valori modificati mentre una transazione è in corso significherebbe modificare il comportamento delle operazioni sul Database attivando la modalità Read_Uncommitted, sinceramente non ho idea di come si possa fare perché non mi è mai passato per la mente di farlo, ma se esiste sicuramente qualcuno la usa, perciò puoi provare.
La documentazione ufficiale di Microsoft relativa al Transaction Isolation Level e come si modifica
Un articolo interessante sulle transazioni e i livelli di transazione.
Se non cambi l'Isolation Level, la lettura attenderà il commit/rollback per darti i risultati quindi se non calibri correttamente le funzionalità rischi un DeadLock sul database. Ovviamente se sei in multiutenza e usi il livello di isolamento Read_uncommitted i tuoi utenti possono ricevere dati inconsistenti e potrebbero generare ulteriori inconsistenze su altri dati.
Una tecnica che un collega ha usato per una operazione dove perdere il dato in corso a causa di un problema dell'utente era possibile ma non auspicabile è stata di inventarsi dei record di tipo "Temporaneo" dove crea il dato transazionale non ancora confermato, scrivendolo sul database, poi quando l'utente consolida il dato viene trasformato in dato definitivo. Ma in questo caso si trattava di una singola tabella di cui duplicava un numero di righe su cui l'utente stava lavorando. Ed era molto semplice buttarle se restavano appese o farle rivedere all'utente. Inoltre venivano utilizzate come mezzo di blocco per evitare che più utenti modificassero lo stesso oggetto, se nel tuo caso ci sono modifiche su varie tabelle potrebbe essere difficile gestirlo con qualcosa di questo genere.
Saluti
Quote from Ferdinando_B on 16/12/2020, 11:20Salve...
Sinceramente non capisco perchè complicarti la vita lasciando tutta la parte di elaborazione sul db.
Nel db dovrebbero finire solo i risultati finali... come fai con la multiutenza? o per modifiche, correzioni di errori, ecc...
Cmq se hai fatto questa scelta credo che siano stati valutati tutti i pro e i contro era solo una riflessione a voce alta che al tuo posto avrei cambiato metodo soprattutto perchè è difficile che un applicativo che gestisce dati ed esegue operazioni, calcoli rimane invariato nel tempo...
arriverai ad un punto che ci saranno così tante stored procedure che verrà complicato la loro gestione. Per non parlare dell'esposizione di queste a tutti quelli che hanno accesso all'istanza.
Per risolvere il tuo problema potresti creare delle tabelle temporanee lato codice che vengono popolate dalle stored procedure e dall'input dell'utente... sucessivamente puoi procedere all'aggiornamento dei dati dalla tabella temporanea al db ufficiale e cancellare la tabella o i valori quando non serve più.
Spero di essere stato di aiuto
Saluti
Ferdinando
Salve...
Sinceramente non capisco perchè complicarti la vita lasciando tutta la parte di elaborazione sul db.
Nel db dovrebbero finire solo i risultati finali... come fai con la multiutenza? o per modifiche, correzioni di errori, ecc...
Cmq se hai fatto questa scelta credo che siano stati valutati tutti i pro e i contro era solo una riflessione a voce alta che al tuo posto avrei cambiato metodo soprattutto perchè è difficile che un applicativo che gestisce dati ed esegue operazioni, calcoli rimane invariato nel tempo...
arriverai ad un punto che ci saranno così tante stored procedure che verrà complicato la loro gestione. Per non parlare dell'esposizione di queste a tutti quelli che hanno accesso all'istanza.
Per risolvere il tuo problema potresti creare delle tabelle temporanee lato codice che vengono popolate dalle stored procedure e dall'input dell'utente... sucessivamente puoi procedere all'aggiornamento dei dati dalla tabella temporanea al db ufficiale e cancellare la tabella o i valori quando non serve più.
Spero di essere stato di aiuto
Saluti
Ferdinando
Quote from Miky on 20/12/2020, 10:44Ciao
Grazie per la risposta ma permettimi di dissentire.
Sicuramente gestire algoritmi di calcolo lato db, è un scelta architetturale oggettiva e non assoluta come dici anche tu, ma nel mio caso, dopo un anno di sviluppo non mi sono mai pentito della scelta fatta, anzi.
Ti spiego perche':
1 - Il software prevede di eseguire calcoli su raggruppamenti, filtri, medie, ecc... su circa 50.000 record ad operazione, a volte anche solo per ottenere un numeretto di risultato. Per quanto io possa essere bravo a programmare, dubito di avere le capacità di ottenere performaces migliori di un db come SQLServer. Avrei dovuto implementare un sacco di programmazione parallela ed il lavoro si sarebbe incentrato molto di piu' sulla risoluzione degli algoritmi anziché sul software di gestione. Senza contare innumerevoli bug, colli di bottiglia e modellazione degli oggetti errata in fase preliminare ecc.
2 - SQLServer permette di poter analizzare il piano di esecuzione delle query, valutarne i tempi di esecuzione e quindi ottimizzare le query gestendo gli indici in maniera oculata. Posso verificare i carichi del db, ecc. Farlo via codice sarebbe quantomeno oneroso in termini di tempo.
3 - Gestire la logica dell'applicazione lato client avrebbe significato verificare costantemente il client utilizzato dagli utenti e magari forzare un aggiornamento o inibire l'utilizzo di una versione deprecata. Gestendo gli algoritmi lato db, non ho questo problema. Se modifico un algoritmo non serve nemmeno rilasciare un nuovo client. Tutto avviene senza che gli utenti nemmeno se ne accorgano. Soluzione validissima anche per la generazione dei report.
4 - I client sono molto leggeri, in quanto implementano solo la parte di visualizzazione dati e convalida degli input.
5 - Il traffico di rete e' esiguo. Se la logica fosse lato client, per poter eseguire i calcoli, avrei dovuto trasferire ogni volta migliaia e migliaia di record e verificare sempre e comunque lo stato di aggiornamento. Nel mio caso invece mi basta semplicemente caricare i dati minimi per poter predisporre un input o un generare un report.
6 - Per la modifica e gestione degli errori lato DB, anche in questo caso non ho nessun problema, anzi. Utilizzando SSDT, lavoro sempre su una copia locale aggiornata del DB di produzione. Sulla copia locale del DB, eseguo tutte le modifiche o aggiornamenti del caso. Prima di aggiornare il DB di produzione verifico tutti cambiamenti. Se si tratta di nuove implementazioni, mi basta eseguire un aggiorna e in meno di un secondo ho il db di produzione aggiornato. Se invece ho modifiche delicate, faccio gli aggiornamenti a mano o comunque con delle transaction tanto per essere sicuro di quello che sto facendo. Una volta aggiornato il DB di produzione, in maniera automatica aggiorno il DB di sviluppo, cosi sono sicuro di essere sempre allineato allo stato reale.
SSDT ti permette di eseguire anche il refactoring, ovvero, supponiamo di voler modificare il nome di un campo, con SSDT in un attimo so in quali View, StoredProcedure, Funzioni, Trigger, ecc... tale campo e' utilizzato. Modificando quindi il nome, tutte le sue occorrenze verrebbero aggiornate.
Non lo faccio mai, però lo uso nel momento in cui voglio rivedere in quali view o sp tale campo e' utilizzato e come, e quindi riorganizzare e migliorare la logica degli algoritmi.
7 - Se domani volessi riscrivere il client da zero, magari web, non dovrei rivedere la logica dell'applicazione, ma solo quello che concerne la parte grafica.
8 - Se penso ad una applicazione bancaria, dubito che in un client vengano scaricati tutti i dati di un utente (magari una grande azienda) solo per verificarne il saldo.
Perdona la risposta così lunga, ma spero di aver dato un punto di vista utile a chi in seguito si porrà delle domande se utilizzare un db solo come storage o anche come motore di calcolo.
Ripeto, e' una scelta architetturale, che deve essere valutata in funzione del progetto da realizzare. Nel mio caso i punti 1,2,3 erano fondamentali per ottenere delle ottime performances e concentrandomi di piu' sullo sviluppo del client, in quanto il software e' entrato in produzione già dalla settimana 2 di sviluppo.
Tornando al topic, l'anteprima dei risultati prima di un salvataggio, nel mio caso, e' un non problema. E' solo una feature secondaria che forse avrei implementato ed una curiosità esternata. Posso rinunciarci tranquillamente, preferisco i vantaggi di cui sopra.
Miky
Ciao
Grazie per la risposta ma permettimi di dissentire.
Sicuramente gestire algoritmi di calcolo lato db, è un scelta architetturale oggettiva e non assoluta come dici anche tu, ma nel mio caso, dopo un anno di sviluppo non mi sono mai pentito della scelta fatta, anzi.
Ti spiego perche':
1 - Il software prevede di eseguire calcoli su raggruppamenti, filtri, medie, ecc... su circa 50.000 record ad operazione, a volte anche solo per ottenere un numeretto di risultato. Per quanto io possa essere bravo a programmare, dubito di avere le capacità di ottenere performaces migliori di un db come SQLServer. Avrei dovuto implementare un sacco di programmazione parallela ed il lavoro si sarebbe incentrato molto di piu' sulla risoluzione degli algoritmi anziché sul software di gestione. Senza contare innumerevoli bug, colli di bottiglia e modellazione degli oggetti errata in fase preliminare ecc.
2 - SQLServer permette di poter analizzare il piano di esecuzione delle query, valutarne i tempi di esecuzione e quindi ottimizzare le query gestendo gli indici in maniera oculata. Posso verificare i carichi del db, ecc. Farlo via codice sarebbe quantomeno oneroso in termini di tempo.
3 - Gestire la logica dell'applicazione lato client avrebbe significato verificare costantemente il client utilizzato dagli utenti e magari forzare un aggiornamento o inibire l'utilizzo di una versione deprecata. Gestendo gli algoritmi lato db, non ho questo problema. Se modifico un algoritmo non serve nemmeno rilasciare un nuovo client. Tutto avviene senza che gli utenti nemmeno se ne accorgano. Soluzione validissima anche per la generazione dei report.
4 - I client sono molto leggeri, in quanto implementano solo la parte di visualizzazione dati e convalida degli input.
5 - Il traffico di rete e' esiguo. Se la logica fosse lato client, per poter eseguire i calcoli, avrei dovuto trasferire ogni volta migliaia e migliaia di record e verificare sempre e comunque lo stato di aggiornamento. Nel mio caso invece mi basta semplicemente caricare i dati minimi per poter predisporre un input o un generare un report.
6 - Per la modifica e gestione degli errori lato DB, anche in questo caso non ho nessun problema, anzi. Utilizzando SSDT, lavoro sempre su una copia locale aggiornata del DB di produzione. Sulla copia locale del DB, eseguo tutte le modifiche o aggiornamenti del caso. Prima di aggiornare il DB di produzione verifico tutti cambiamenti. Se si tratta di nuove implementazioni, mi basta eseguire un aggiorna e in meno di un secondo ho il db di produzione aggiornato. Se invece ho modifiche delicate, faccio gli aggiornamenti a mano o comunque con delle transaction tanto per essere sicuro di quello che sto facendo. Una volta aggiornato il DB di produzione, in maniera automatica aggiorno il DB di sviluppo, cosi sono sicuro di essere sempre allineato allo stato reale.
SSDT ti permette di eseguire anche il refactoring, ovvero, supponiamo di voler modificare il nome di un campo, con SSDT in un attimo so in quali View, StoredProcedure, Funzioni, Trigger, ecc... tale campo e' utilizzato. Modificando quindi il nome, tutte le sue occorrenze verrebbero aggiornate.
Non lo faccio mai, però lo uso nel momento in cui voglio rivedere in quali view o sp tale campo e' utilizzato e come, e quindi riorganizzare e migliorare la logica degli algoritmi.
7 - Se domani volessi riscrivere il client da zero, magari web, non dovrei rivedere la logica dell'applicazione, ma solo quello che concerne la parte grafica.
8 - Se penso ad una applicazione bancaria, dubito che in un client vengano scaricati tutti i dati di un utente (magari una grande azienda) solo per verificarne il saldo.
Perdona la risposta così lunga, ma spero di aver dato un punto di vista utile a chi in seguito si porrà delle domande se utilizzare un db solo come storage o anche come motore di calcolo.
Ripeto, e' una scelta architetturale, che deve essere valutata in funzione del progetto da realizzare. Nel mio caso i punti 1,2,3 erano fondamentali per ottenere delle ottime performances e concentrandomi di piu' sullo sviluppo del client, in quanto il software e' entrato in produzione già dalla settimana 2 di sviluppo.
Tornando al topic, l'anteprima dei risultati prima di un salvataggio, nel mio caso, e' un non problema. E' solo una feature secondaria che forse avrei implementato ed una curiosità esternata. Posso rinunciarci tranquillamente, preferisco i vantaggi di cui sopra.
Miky