Sincronização de dados offline

A sincronização de dados offline é um recurso do SDK dos Aplicativos Móveis do Azure. Os dados são armazenados em um armazenamento local. Quando seu aplicativo está offline, você ainda pode criar, modificar e pesquisar os dados. Os dados são sincronizados com o serviço Aplicativos Móveis do Azure quando o dispositivo está online. O SDK oferece suporte à resolução de conflitos quando o mesmo registro é alterado no cliente e no serviço.

A sincronização offline tem vários benefícios:

  • Melhora a capacidade de resposta do aplicativo
  • Melhora a confiabilidade do aplicativo quando há conectividade de rede ruim
  • Limita o uso da rede em redes limitadas ou de alta latência
  • Suporta uso desconectado

Os tutoriais a seguir mostram como adicionar sincronização offline aos seus clientes móveis usando os Aplicativos Móveis do Azure:

O que é uma tabela de sincronização?

Os SDKs de Aplicativos Móveis do Azure fornecem IRemoteTable<T>, que acessa o serviço diretamente. A operação falhará se o dispositivo não tiver uma conexão de rede. Uma tabela de sincronização (fornecida por IOfflineTable<T>) fornece as mesmas operações em relação a um armazenamento local. A loja local pode então ser sincronizada com o serviço posteriormente. Antes de executar qualquer operação, você deve inicializar o armazenamento local.

O que é uma loja local?

Um armazenamento local é a camada de persistência de dados no dispositivo cliente. A maioria das plataformas usa SQLite para o armazenamento local, mas o iOS usa Core Data. Você também pode implementar sua própria loja local. Por exemplo, use uma versão do SQLite com SQLCipher para produzir um armazenamento criptografado.

Como funciona a sincronização offline?

O código do cliente controla quando as alterações locais são sincronizadas com um serviço de sincronização de dados. Nada é enviado para o serviço até que você envie as alterações locais. Da mesma forma, o armazenamento local é preenchido com dados novos ou atualizados somente quando você extrai dados.

Você pode enviar por push operações pendentes para todas as tabelas, uma lista de tabelas ou uma tabela:

// All tables
await client.PushTablesAsync();

// A list of tables
var tablesToPush = new string[] { "table1", "table2" };
await client.PushTablesAsync(tablesToPush);

// A single table
await table.PushItemsAsync();

Sincronização

A operação push envia todas as alterações pendentes na fila de operações para o serviço. A alteração pendente é enviada para o serviço por meio de uma chamada HTTP REST, que por sua vez modifica seu banco de dados.

As operações push são feitas antes de qualquer operação pull. A operação pull extrai dados alterados do serviço e os armazena no repositório local.

Impulso implícito

Se você executar um pull contra uma tabela que tenha atualizações locais pendentes, o pull primeiro executará um push para essa tabela. Esse push ajuda a minimizar conflitos entre alterações que já estão enfileiradas e novos dados do servidor. Opcionalmente, você pode configurar um push de todas as tabelas definindo PushOtherTables em PullOptions:

var pullOptions = new PullOptions { PushOtherTables = true };
await table.PullItemsAsync(pullOptions);

Puxando um subconjunto de registros

Você pode, opcionalmente, especificar uma consulta que é usada para determinar quais registros devem ser incluídos no banco de dados offline. Por exemplo:

var query = table.CreateQuery().Where(x => x.Color == "Blue");
await table.PullItemsAsync(query);

Sincronização incremental

Os Aplicativos Móveis do Azure implementam a sincronização incremental. Apenas os registos que foram alterados desde a última operação de puxar são extraídos. A sincronização incremental economiza tempo e largura de banda quando você processa tabelas grandes.

Para cada consulta exclusiva, o UpdatedAt campo do último registro transferido com êxito é armazenado como um token no repositório offline. O último UpdatedAt valor é armazenado no armazenamento de token delta. O repositório delta-token é implementado como uma tabela no repositório offline.

Desempenho e consistência

Às vezes, a sincronização é interrompida prematuramente. Por exemplo:

  • A rede que você está usando para sincronização fica indisponível durante o processo de sincronização.
  • Você força o fechamento do aplicativo durante a sincronização.

Para minimizar o risco de um problema de consistência no banco de dados offline, cada registro é gravado no banco de dados à medida que é recebido. Você pode, opcionalmente, decidir gravar os registros no banco de dados em lotes. As operações em lote aumentam o desempenho das gravações do banco de dados offline durante a operação de receção. No entanto, eles também aumentam o risco de uma inconsistência entre os metadados da tabela e os dados dentro da tabela.

Você pode ajustar o intervalo entre as gravações da seguinte maneira:

var pullOptions = new PullOptions { WriteDeltaTokenInterval = 25 };
await table.PullItemsAsync(pullOptions);

Esse código reúne gravações em lotes de 25 registros. Os testes de desempenho sugerem que o desempenho melhora até um valor de 25. Um WriteDeltaTokenInterval valor superior a 25 não melhora significativamente o desempenho.

Purga

Você pode limpar o conteúdo do repositório local usando IOfflineTable<T>.PurgeItemsAsync. A limpeza pode ser necessária se você tiver dados obsoletos no banco de dados cliente ou se quiser descartar todas as alterações pendentes. Uma limpeza limpa uma mesa da loja local. Para limpar uma tabela:

await table.PurgeItemsAsync("", new PurgeOptions());

O PurgeItemsAsync() método lança um InvalidOperationException erro se houver alterações pendentes na tabela. Neste caso, você pode forçar a purga a acontecer:

await table.PurgeItemsAsync("", new PurgeOptions { DiscardPendingOperations = true });

A limpeza é um último recurso para limpar uma tabela na loja offline, porque limpa todos os registros do cache e exige que você os baixe novamente.