Azure应用服务 - 脱机同步 - PullAsync事务

时间:2017-06-29 12:41:48

标签: android ios azure xamarin azure-mobile-services

我正在开发一个使用Xamarin.Forms和Azure App Service的应用程序。 用户必须显式执行数据同步。当用户启动数据同步时,会执行许多此方法以从服务器获取当前数据:

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

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

编辑:

为了更容易理解:我们假设我有一个表“ToDoItem”和“ToDoCategory”。用户启动数据同步。数据同步运行并成功检索所有ToDoItem。在下一步中,数据同步将获得ToDoCategories(对PullAsync的另一个调用),但在此之前用户关闭应用程序。现在我拥有所有ToDoItems但没有ToDoCategories。但该应用程序不适用于没有ToDoCategories。这是一个非常简单的例子。实际项目中的数据结构要复杂得多。实体之间存在很多依赖关系。

记录同步错误/取消并在下次应用启动时提示用户进行其他同步是无法解决的问题。假设在下一个应用程序启动时,用户没有互联网连接,无法执行数据同步。我无法锁定应用程序单元以进行下一次成功的数据同步。

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

2 个答案:

答案 0 :(得分:1)

  

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

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

  

记录同步错误/取消并在下次应用启动时提示用户进行其他同步是无法解决的问题。假设在下一个应用程序启动时,用户没有互联网连接,无法执行数据同步。我无法锁定应用程序单元下一次成功的数据同步。

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

还要考虑用户离开后应用可能会在后台继续同步。在iOS中,您必须使用UIApplication beginBackgroundTaskWithExpirationHandler协调操作系统。

答案 1 :(得分:0)

  

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

如果您指定查询ID(非空),则可以使用增量同步进行提取操作。正如官方document提到的有关增量同步的内容:

  

pull操作的第一个参数是仅在客户端上使用的查询名称。如果使用非空查询名称,则Azure Mobile SDK将执行增量同步。 每次pull操作返回一组结果时,该结果集中的最新updatedAt时间戳存储在SDK本地系统表中。后续拉取操作仅检索该时间戳之后的记录

成功检索数据并更新到本地数据存储后,客户端SDK将更新/插入__config表,其中包含来自提取结果的最新updatedAt时间戳以及id等于deltaToken|{table-name}|{query-id}对于您的SQLite数据库,如下所示:

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

假设您已检索到TodoItem表的50条记录。

  

BEGIN TRANSACTION

     

INSERT或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或IGNORE INTO [__config]([id])VALUES(@ p0)

     

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

     

COMMIT TRANSACTION

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