5

情况:我有一个数据库和一个 Web 应用程序,它们可以交互以显示和更新科学数据表。我的任务是构建一个移动应用程序,允许用户

  1. 为跟踪目的离线验证和识别自己(使用预定义但动态的用户帐户和存储在缓存中的权限)
  2. 下载现场工作的识别数据(通过互联网访问)
  3. 在现场进行和存储观察(没有互联网访问)
  4. 稍后将观察结果同步到在线数据库

问题:验证/下载/存储/上传必要数据以管理此类独立于一致互联网访问的应用程序的最佳方法是什么?如果两个人调整了相同的读数,并且在同步之间发生了一次更新,我如何跟踪哪些表和值已被更改,并防止更改丢失?

当前思路:我目前关于碰撞控制的暂定策略是维护一个“同步”表,该表存储 JSON 对象,代表存储在 sessionStorage 中的每个在线数据库事务,并让应用程序在上传数据之前不断验证其同步,并检查此对象是否更新特定主键的潜在冲突。我希望能够在元组处于编辑阶段时锁定元组,但由于互联网访问不一致,这似乎是不可能的。

抱歉,如果这是一个新问题,我对整个移动应用程序开发都是新手......

tl;dr如何防止移动应用程序对数据库的异步更改覆盖/与另一个人对同一数据库的更改发生冲突?以及如何验证没有网络连接的用户?

4

3 回答 3

2

您是否听说过关于ajax 调用的“竞争条件” [1] ?有一个解决方案[2],您可以如何使您的 ajax 调用顺序而不是并发地对您的服务器进行调用,因此它们一个接一个地依次运行。这适用于异步连接,因此不需要任何其他同步操作。

这里的诀窍是为此目的使用 jQuery ajaxQueue [3]

我的消息来源:

[1] http://en.wikipedia.org/wiki/Race_condition

[2]如何让所有的 AJAX 调用按顺序进行?

[3] http://plugins.jquery.com/ajaxqueue/

于 2013-08-31T13:56:56.847 回答
2

对于未连接到网络的用户身份验证,我将建议以下路径:

在第 2 点,您正在通过互联网访问下载识别数据。因此,显然您必须在本地存储中以加密格式保存用户名和密码对。这是唯一可以帮助您在访问远程区域(即离线模式)的应用程序时在同一设备上验证同一用户的方法。最终,手持设备是每个用户的,您的应用程序将只保留该用户的历史记录;在这种情况下,我认为这绝对没问题。

为了避免碰撞;我会建议增加设备与主服务器同步的次数。如果用户在网络中并且他们对数据进行了一些修改,那么后台同步操作应该将这些更改同步到主服务器,其他用户应该在预定义的时间间隔后同步。同步数据的时间更长;发生冲突的可能性较小。但同样的问题仍然是用户处于离线模式时对数据进行的修改。为此我们无能为力。您的冲突管理代码应该具有一些智能,例如哪个数据副本应该具有更多偏好,即来自具有 A 安全角色的 X 用户的数据或来自具有 B 安全角色的 Y 用户的数据或类似的东西。

于 2013-09-04T12:10:04.917 回答
2

至于同步,你可以看看jIO——我们正在开发的一个开源库,它可以跨不同类型的存储同步 JSON 文档,并且有一个超级简单的 API。

有许多可用的连接器(webDav、S3、xwiki 等)可用并且正在开发中,您还可以编写自己的连接器来将 JIO 连接到您提供 JSON 数据的任何位置。

然后在客户端上,您可以使用客户端 localhost 和远程存储作为存储来设置复制修订存储:

 var jio_instance = jIO.newJio({
   "type": "replicaterevision",
   "storage_list": [{
     "type": "revision",
     "sub_storage": {<storage spec for your localhost storage>}
    }, {
     "type": "revision",
     "sub_storage": {<storage spec for your remote storage>}
    }]
 });

中的所有存储都storage_list将自动进行版本控制和同步。因此,如果用户离线,检索文档,编辑并保存它(仅限本地存储,因为用户离线),jIO 将在用户下次尝试在线访问文件时引发冲突,因为当前版本在remote-storagelocalstorage不同。

那么只需要编写一个例程来解决多个用户在在线/离线时编辑文档引起的任何冲突=保留/合并/等的版本。

访问文档相当简单。JSON 文档具有元数据和附件,您可以使用以下命令来修改您的 JSON 文档:

  POST  > generate a new document
  PUT > update existing document
  GET > retrieve a document
  REMOVE > delete a document
  ALLDOCS > retrieve all documents
  PUTATTACHEMENT > add an attachment to a document
  GETATTACHEMENT > retrieve an attachment from a document
  REMOVEATTACHEMENT > delete an attachement from a document

像这样调用:

  jio_instance.get({"_id":"your_doc_id"}, function (err, response) {
    // do something
  });

JIO 还有一个complex-queries模块,它允许在你的存储上运行类似数据库的查询。所以你可以做这样的事情:

options = {
 query: '(author:"% Doe") AND (format:"pdf")',
 limit: [0, 100],
 sort_on: [['last_modified', 'descending'], ['creation_date', 'descending']],
 select_list: ['title'],
 wildcard_character: '%'
};

// run query
jio_instance.allDocs(options, function (error, response) {
  // do sth
});

如果您有任何问题,请告诉我。

于 2013-09-03T11:12:43.223 回答