Azure 应用服务 - 离线同步 - PullAsync 事务

Azure App Service - Offline Sync - PullAsync Transaction

我正在开发一个使用 Xamarin.Forms 和 Azure 应用服务的应用程序。 用户必须明确执行数据同步。当用户开始数据同步时,会执行很多这样的方法来从服务器获取当前数据:

 await this.ISyncTable.PullAsync(queryId, query, cancellationToken).ConfigureAwait(false);

我的问题:应用程序可能会进入不一致状态。例如,当用户在数据同步完成之前关闭应用程序时。在此状态下,应用程序无法使用。

编辑:

为了更容易理解:假设我有一个 table "ToDoItem" 和 "ToDoCategory"。用户开始数据同步。数据同步 运行s 和所有 ToDoItems 已成功检索。在下一步中,数据同步将获取 ToDoCategories(对 PullAsync 的另一个调用),但在此之前用户关闭应用程序。现在我有所有 ToDoItems 但没有 ToDoCategories。但是如果没有 ToDoCategories,该应用程序将无法使用。这是一个非常简单的例子。实际项目中的数据结构要复杂得多。实体之间有很多依赖关系。

记录同步错误/取消并在下次应用启动时提示用户进行另一次同步不是解决方案。假设在下次启动应用程序时,用户没有互联网连接并且无法执行数据同步。在下一次成功的数据同步之前,我无法锁定应用程序。

有没有办法在一个事务中 运行 多个 PullAsync 操作?

My problem: The application can get into an inconsistent state. For example when the user closes the App before the data sync is completed. In this state the App is not usable.

如果您指定查询 ID(非空),那么您将使用 增量同步 进行拉取操作。正如官方 document 提到的增量同步:

the first parameter to the pull operation is a query name that is used only on the client. If you use a non-null query name, the Azure Mobile SDK performs an incremental sync. Each time a pull operation returns a set of results, the latest updatedAt timestamp from that result set is stored in the SDK local system tables. Subsequent pull operations retrieve only records after that timestamp.

成功检索数据并更新到本地数据存储后,客户端 SDK 将 update/insert __config table 具有来自拉取结果的最新 updatedAt 时间戳以及SQLite 数据库的 ID 等于 deltaToken|{table-name}|{query-id},如下所示:

此外,在检索记录后,客户端 SDK 将执行以下 sql 语句来更新您的本地数据存储:

假设您已经为 TodoItem table.

检索了 50 条记录

BEGIN TRANSACTION

INSERT OR IGNORE INTO [TodoItem] ([id]) VALUES (@p0),(@p1),(@p2),(@p3),(@p4),(@p5),(@p6),(@p7),(@p8),(@p9),(@p10),(@p11),(@p12),(@p13),(@p14),(@p15),(@p16),(@p17),(@p18),(@p19),(@p20),(@p21),(@p22),(@p23),(@p24),(@p25),(@p26),(@p27),(@p28),(@p29),(@p30),(@p31),(@p32),(@p33),(@p34),(@p35),(@p36),(@p37),(@p38),(@p39),(@p40),(@p41),(@p42),(@p43),(@p44),(@p45),(@p46),(@p47),(@p48),(@p49)

UPDATE [TodoItem] SET [Text] = @p0,[UserId] = @p1 WHERE [id] = @p2

UPDATE [TodoItem] SET [Text] = @p0,[UserId] = @p1 WHERE [id] = @p2

.

.

COMMIT TRANSACTION

BEGIN TRANSACTION

INSERT OR IGNORE INTO [__config] ([id]) VALUES (@p0)

UPDATE [__config] SET [value] = @p0 WHERE [id] = @p1

COMMIT TRANSACTION

默认MaxPageSize for pullasync是50,如果三个有更多数据,客户端会自动发送多个请求。注意在页面中检索记录后,检索到的数据将更新到您的本地数据存储,然后将发送下一个页面请求。根据我的理解,如果用户在数据同步完成之前关闭应用程序,则数据不会更新到最新,当用户再次打开应用程序时,丢失的数据将根据最新更新到您的数据存储中更新时间戳。

Is there a way to run multiple PullAsync operations in a transaction?

简短的回答是否定的,没有。当所有 PullAsync 操作完成时设置一个标志,或跟踪哪些表已成功同步。

It is no solution to log the sync error / cancellation and prompt the user at the next app start for another sync. Assume on the next app start the user has no internet connection and cannot perform a data sync. I cannot lock the app unitl the next successful data sync.

如果用户开始同步但在同步完成前离开了应用,您的应用在第二次 运行 上的预期行为是什么?完成同步?提示用户重新开始?

还要考虑到应用可能会在用户离开后继续在后台同步。在 iOS 中,您必须使用 UIApplication beginBackgroundTaskWithExpirationHandler.

与操作系统协调