Autore Topic: Algoritmo sincronizzazione database  (Letto 818 volte)

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Algoritmo sincronizzazione database
« il: 02 Novembre 2015, 15:31:54 CET »
0
Se qualcuno ha già affrontato questo problema mi piacerebbe sentire come avete fatto.
Il problema è quello di sincronizzare un database locale con un server dove la sincronizzazione deve avvenire tra più dispositivi.
L'idea è quella di aggiungere un campo ultima_modifica ad ogni record specificando il momento della modifica. Per i record cancellati l'idea sarebbe aggiungere un flag cancellato ad ogni record, quindi la cancellazione dal database sarebbe virtuale e non fisica. La sincronizzazione dovrebbe avvenire al lancio dell'App (dal server al dispositivo) e alla chiusura (dal dispositivo al server).
Mi sorge tuttavia qualche dubbio su possibili conflitti tra vari dispositivi, es. come ricavare il tempo? (che potrebbe variare da dispositivo a dispositivo).
E se più dispositivi utilizzano l'app contemporaneamente? (Fare una sincronizzazione in ambo le direzioni sia all'avvio che alla chiusura?)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Algoritmo sincronizzazione database
« Risposta #1 il: 02 Novembre 2015, 15:59:38 CET »
0
Sono d'accordo con il campo ultima_modifica e con il flag per la cancellazione virtuale.

Per il problema del tempo, potrebbe bastare farlo inserire dal database server, per esempio usando NOW() nell'SQL di modifica.

Per il problema dell'accesso concorrente da parte di più app, ovviamente non è proprio possibile garantire la coerenza tra tutto e tutti in ogni momento. Cerca di spostare la risoluzione dei conflitti direttamente a livello di database server, così è lo stesso database engine ad arbitrare i vari accessi. Nella tua app poi dovrai tenere conto che tra l'apertura e la chiusura altre app potrebbero aver modificato il contenuto, per cui sarà opportuno richiedere aggiornamenti (se necessario).
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline LonelyWolf

  • Utente junior
  • **
  • Post: 148
  • Respect: +12
    • Mostra profilo
    • Traversate dei laghi
  • Dispositivo Android:
    GT-I9505, ALE-L21
  • Sistema operativo:
    Windows 7 32/64
Re:Algoritmo sincronizzazione database
« Risposta #2 il: 02 Novembre 2015, 17:19:47 CET »
0
Preciso che utilizzando il tempo del server (soluzione più corretta e logica anche secondo me), devi anche tener presente il delta tra dispositivo e server.
Se la mia risposta ti è utile, per favore un thanks!

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Algoritmo sincronizzazione database
« Risposta #3 il: 02 Novembre 2015, 17:44:09 CET »
0
Potrei inserire il tempo -1 quando modifico il database locale, e poi quando lo sincronizzo col server aggiornare tale tempo col tempo del server. E' un po' macchinoso, ma fattibile.

Tuttavia temo che la sincronizzazione in entrambe le direzioni all'apertura e chiusura dell'app non sia sufficiente. Niente mi garantisce che due dispositivi dello stesso utente lancino due sincronizzazioni contemporaneamente, anche se nella mia app questa è un'ipotesi molto improbabile. Bisognerebbe sincronizzare (nel senso di synchronized) i metodi sul server per singolo utente, ma dubito che sia possibile.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Algoritmo sincronizzazione database
« Risposta #4 il: 03 Novembre 2015, 07:58:25 CET »
0
Tuttavia temo che la sincronizzazione in entrambe le direzioni all'apertura e chiusura dell'app non sia sufficiente. Niente mi garantisce che due dispositivi dello stesso utente lancino due sincronizzazioni contemporaneamente, anche se nella mia app questa è un'ipotesi molto improbabile. Bisognerebbe sincronizzare (nel senso di synchronized) i metodi sul server per singolo utente, ma dubito che sia possibile.

Ma questo accade anche per le pagine web, persino per questo forum, dove due utenti possono rispondere allo stesso post contemporaneamente. Devi "semplicemente" accettare che possa accadere e gestire la situazione quando accade. Inutile pensare a metodi complicati per evitare che accada.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Algoritmo sincronizzazione database
« Risposta #5 il: 03 Novembre 2015, 09:00:01 CET »
0
Si ma supponiamo che cellulare 1 che ha come ultima modifica 5 faccia delle operazioni e poi le carichi sul server al tempo 7. Se nel frattempo cellulare 2 ha caricato delle modifiche con tempo 6, cellulare 1 non le acquisirà mai.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Algoritmo sincronizzazione database
« Risposta #6 il: 03 Novembre 2015, 09:19:50 CET »
0
Si ma supponiamo che cellulare 1 che ha come ultima modifica 5 faccia delle operazioni e poi le carichi sul server al tempo 7. Se nel frattempo cellulare 2 ha caricato delle modifiche con tempo 6, cellulare 1 non le acquisirà mai.

Immagina questo stesso scenario in un forum... è assolutamente normale che accada.

Se non vuoi che accada, secondo me devi gestirlo "lato server", annullando la seconda modifica se eseguita in base a dati già vecchi. Ma per fare questo devi tenere traccia anche della versione di partenza di ciascuna modifica e passarla al server stesso.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline wlf

  • Utente normale
  • ***
  • Post: 315
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Algoritmo sincronizzazione database
« Risposta #7 il: 03 Novembre 2015, 09:23:55 CET »
0
Si ma supponiamo che cellulare 1 che ha come ultima modifica 5 faccia delle operazioni e poi le carichi sul server al tempo 7. Se nel frattempo cellulare 2 ha caricato delle modifiche con tempo 6, cellulare 1 non le acquisirà mai.

In questi casi devi gestirti tu questo "conflitto"; per sommi capi la modifica di un record comporta che uno dei due lati "vinca". Se un dato è modificabile sia lato server che client, facciamo l'esempio di una anagrafica, o lo imposti con "server win" o con "client win". Nel caso che hai 2 client allora il primo che arriva è quello che modifica il dato ed il secondo lo sovrascrive ... ;)

Potresti cercare di sfruttare il GCM mandando il record modificato dal server ai client in modo da avvertire il secondo dispositivo che non ha ancora sincronizzato che il record che sta inviando nel frattempo è stato modificato, e da questo gestirti le eventuali differenze e politiche che vuoi applicare ...  ;)
Oppure puoi fare un controllo tra record originale e quello del secondo dispositivo avvertendo l'utente che nel frattempo il record che sta mandando è stato modificato, quindi potresti tenerti le modifiche "parcheggiate" facendo preventivamente una sincronizzazione e poi dalla tua App puoi decidere come procedere, "server win" o "client win", oppure potresti pure fare un "merge" secondo delle tue particolari esigenze ... ;)


Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Algoritmo sincronizzazione database
« Risposta #8 il: 03 Novembre 2015, 10:25:57 CET »
0
Non intendevo modifiche agli stessi record (in questo caso mi sembra giusto far prevalere l'ultima modifica) ma aggiunte di nuovi record che certi client potrebbero perdere.
Esempio:
- client1 aggiunge dei record al database locale
- client1 viene chiuso e avvia una sincronizzazione: scarica i nuovi record dal server e carica i propri nuovi record con tempo 7
- dopo che client1 ha scaricato i nuovi record dal server e un istante prima che carichi i propri nuovi record, client 2 aggiunge nuovi record con tempo6. Questi nuovi record con tempo 6 non saranno mai acquisiti da client1 perché il suo tempo ora è 7, e quindi li vede come cose vecchie. Questo vale anche x modifiche e cancellazioni.


Offline LonelyWolf

  • Utente junior
  • **
  • Post: 148
  • Respect: +12
    • Mostra profilo
    • Traversate dei laghi
  • Dispositivo Android:
    GT-I9505, ALE-L21
  • Sistema operativo:
    Windows 7 32/64
Re:Algoritmo sincronizzazione database
« Risposta #9 il: 03 Novembre 2015, 11:59:35 CET »
0
Non puoi gestire il tempo a blocchi e pretendere che il "durante" sia sincronizzato correttamente; l'unico modo per gestire (soprattutto il caso che hai appena scritto) il tempo corretto è quello di associare il timestamp del server ad ogni record e non a gruppi di record.

Indicativamente:
Avvio applicazione -> richiesta timestamp del server -> calcolo delta con il dispositivo -> richiesta dei record modificati con time dispositivo+delta (ovvero timestamp del server).
aggiunta/modifica dei record sul dispositivo associando timestamp del server (time dispositivo+delta) -> sincronizzazione con server (invio/ricezione record e relativo timestamp associato) -> chiusura app.

il server a questo punto può anche solo fare gli aggiornamenti in ordine di timestamp che è uguale per ogni record, a meno che qualcuno non cambi l'ora al proprio dispositivo dopo aver fatto la prima sincronizzazione!
« Ultima modifica: 03 Novembre 2015, 12:01:20 CET da LonelyWolf »
Se la mia risposta ti è utile, per favore un thanks!

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Algoritmo sincronizzazione database
« Risposta #10 il: 03 Novembre 2015, 14:28:29 CET »
0
La sincronizzazione pensavo di gestirla come transazione: o va a buon fine tutta oppure niente.  Mi sembra il metodo migliore.
Ma anche se la facessi x singoli record il problema si ripresenta tale e quale: client1 scarica 1 record dal server con tempo 5; client2 carica 1 record sul server con tempo 6; client1 carica 1 record sul server con tempo 7 ed ecco che il client1 si è perso per sempre il record 6.

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Algoritmo sincronizzazione database
« Risposta #11 il: 03 Novembre 2015, 15:19:32 CET »
0
Ma anche se la facessi x singoli record il problema si ripresenta tale e quale: client1 scarica 1 record dal server con tempo 5; client2 carica 1 record sul server con tempo 6; client1 carica 1 record sul server con tempo 7 ed ecco che il client1 si è perso per sempre il record 6.

Non c'è modo di evitare lo scenario che descrivi. Ci devi convivere (come ci convivi ad esempio nei messaggi di messaggistica in cui ti capita di inviare un messaggio mentre il tuo interlocutore sta mandando il suo, e scopri che lui lo aveva mandato prima che tu mandassi il tuo). Per esempio permettendo aggiornamenti successivi all'inserimento (quindi non perso per sempre).
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline LonelyWolf

  • Utente junior
  • **
  • Post: 148
  • Respect: +12
    • Mostra profilo
    • Traversate dei laghi
  • Dispositivo Android:
    GT-I9505, ALE-L21
  • Sistema operativo:
    Windows 7 32/64
Re:Algoritmo sincronizzazione database
« Risposta #12 il: 03 Novembre 2015, 15:48:35 CET »
0
La sincronizzazione pensavo di gestirla come transazione: o va a buon fine tutta oppure niente.  Mi sembra il metodo migliore.
Ma anche se la facessi x singoli record il problema si ripresenta tale e quale: client1 scarica 1 record dal server con tempo 5; client2 carica 1 record sul server con tempo 6; client1 carica 1 record sul server con tempo 7 ed ecco che il client1 si è perso per sempre il record 6.

Associando il timestamp ad ogni record client1 si è perso il record 6 fino alla prossima sincronizzazione non per sempre; in fase di chiusura dell'app quando sincronizza le proprie operazioni (inviando) può richiedere le modifiche arrivate al server successive al timestamp della sincronizzazione iniziale (quando si apre l'app); dovrebbe anche memorizzare il timestamp di chiusura in modo da richiedere, all'avvio successivo, le modifiche intervenute dopo.

Questo per quanto riguarda la questione di sincronizzazione dei dati, cosa fare con i dati sincronizzati è un altro paio di maniche: se 2 client modificano lo stesso record, quale client ha ragione (ovvero quali dati devono rimanere)?

Edit:
E le notifiche push?
« Ultima modifica: 03 Novembre 2015, 15:50:50 CET da LonelyWolf »
Se la mia risposta ti è utile, per favore un thanks!

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Algoritmo sincronizzazione database
« Risposta #13 il: 03 Novembre 2015, 21:48:40 CET »
0
Leggete qui forse può essere di aiuto http://www.philipotoole.com/replicating-sqlite-using-raft-consensus/

Inviato dal mio Nexus 5 utilizzando Tapatalk

adb logcat | tee /tmp/logcat | grep TAG

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Algoritmo sincronizzazione database
« Risposta #14 il: 03 Novembre 2015, 23:05:32 CET »
0
in fase di chiusura dell'app quando sincronizza le proprie operazioni (inviando) può richiedere le modifiche arrivate al server successive al timestamp della sincronizzazione iniziale (quando si apre l'app)

In effetti questa potrebbe essere una soluzione... :-)