如何正确处理 SAP Kapsel 离线应用 OData 冲突?
How to handle SAP Kapsel Offline app OData conflicts properly?
我构建了一个能够使用 SAP Kapsel 插件离线存储 OData 的应用程序。
或多或少它与 WEB ID 生成的相同或类似于此示例中的应用程序:https://blogs.sap.com/2017/01/24/getting-started-with-kapsel-part-10-offline-odatasp13/
现在我要检查潜在的错误解决方案。我创建了一个同步冲突(离线数据库存储后在服务器上更改数据并在应用程序上更改了一些内容并开始刷新)。
如文档中所述,我可以在 ErrorArchive 中看到错误,还可以看到一些详细信息。但是我缺少的是数据库中 "current" 数据的信息。
在错误详情中我只能看到设备上的数据,但看不到服务器上更改的数据。
例如:
- 设备正在将一些名称加载到离线商店
- 设备离线
- 用户 A 正在更改一些名称
- 用户 B 正在直接在线更改其中一个名字
- 用户 A 再次在线并开始同步
- 用户 A 现在通知已更改的实体但是:
- 不是用户B输入的内容
我刚看到 "offline" 数据。
有没有一种解决方案可以在一种比较视图中查看 "current" 和 "offline"?
另请注意,服务器通信是由 Kapsel 插件完成的,而不是通过正常的 AJAX 调用。这可能是一种替代方法,但我想知道是否没有 API?
支持的更智能的方法
与此同时,我想出了如何加载在线数据(手动)。
这可以通过将 http 处理程序切换回普通处理程序来完成。
sap.OData.removeHttpClient();
sap.OData.applyHttpClient();
无论如何,这看起来不是一个合适的解决方案,我也有冲突日志本身的问题。必须先删除它,然后才能应用任何刷新。
我找不到任何合适的文档。 SAPUI5 和 SAP Kapsel 文档中也几乎没有描述 ETag 处理。
默认解决方案是SMP 或HCPms 通过ETag 检测错误。在客户端,没有 API 可以在发生冲突时操纵 ETag。在设备上实现一种差异视图的潜在解决方案如下所示:
- 显示错误
- 缓存错误(可能只在内存中?)
- 删除错误
- 刷新数据库
- 使用当前数据和缓存的错误构建差异视图
想法
sap.OData.removeHttpClient();
sap.OData.applyHttpClient();
也可以工作,但可能非常棘手并且可能会产生副作用。
也许某些请求是针对 "wrong" 后端触发的。
由于其含义,这个问题真的很棘手。我了解到您正在模拟由于并发修改而导致的同步错误,并且想知道客户端是否有办法获取“当前”服务器状态,以便为用户提供一种比较本地和服务器状态的方法。
首先,让我给你一个简短的回答:不,当出现同步错误时,客户端无法通过离线API“参考”当前服务器状态。如上所述进行在线查询可能可行,但这肯定是个坏主意。
现在是更长的答案,这解释了为什么这不一定是缺陷以及为什么我说答案有很多含义。
同步错误的类型
We distinguish a number of synchronization errors,在这种情况下,我们显然是在处理与业务相关的问题。这里有两个子类型:用户可以更正的子类型,例如验证错误,以及业务流程本身的问题。
如果用户超出输入范围,例如通过为产品设置负价格,服务器将回复相应的消息:“-1 不是 'Price' 的有效输入值”。作为开发人员,您可以从错误存档中向用户显示此类消息,随后的修复确实非常简单。
现在,当我们谈论并发修改时,事情变得非常非常糟糕。事实上,我想说,在这种情况下,业务流程存在问题,因为一方面,我们允许数据不同步。另一方面,该过程允许多个用户操纵同一条信息。现在应该如何通知和同步所有相关用户,不再只是一个技术细节,而是一个新的业务流程。只是没有办法通用地设计如何处理这种情况。在大多数情况下,这将涉及需要决定如何合并更改的后台专家。
更好的解决方案
Angstrom 指出没有办法在客户端操作 ETag,事实上你甚至不应该考虑它。 ETag 在乐观锁定场景中的工作方式类似于版本号,更改 ETag 基本上意味着“只是覆盖服务器上的内容”。在严重的情况下这是不行的。
可接受的解决方法如下:
- 确保服务器 returns 详细的错误消息,以便用户可以看到发生了什么以及导致冲突的原因。
- 如果这没有帮助,请刷新数据。这将为您提供更新的 ETag,并将本地更改合并到“当前”服务器状态,但仅限于本地。 “合并”实际上意味着本地更改总是覆盖远程更改。
- 用户现在有另一个机会查看数据并可以再次提交。
一个好的解决方案
更好不一定好,所以这是你真正应该做的:永远不要让并发修改发生,因为处理它真的很昂贵。这意味着开发人员不应该解决此问题,但业务需要更改流程。
正确的问题是,“当您在分布式系统中复制数据时,为什么要允许同时修改它?”通常利益相关者不会喜欢这类问题,适当的反应是与他们一起制定冲突解决流程。只有到那时,他们才会意识到修复这种不同步的成本是多么高昂,而且他们通常会发现调整流程比坚持另一个后台流程来解决它引起的问题要便宜得多。即使他们坚持认为需要进行这种并发修改,他们现在也会明白解决这个问题不是你的任务,他们需要投资解决冲突的过程。
TL;DR
无法将服务器和客户端状态与客户端上的服务器状态进行比较,但您可以进行刷新以保留本地更改并获取更新的 ETag。然而,真正的解决办法是重做业务流程,因为这不再是一个纯粹的技术问题。
我构建了一个能够使用 SAP Kapsel 插件离线存储 OData 的应用程序。 或多或少它与 WEB ID 生成的相同或类似于此示例中的应用程序:https://blogs.sap.com/2017/01/24/getting-started-with-kapsel-part-10-offline-odatasp13/
现在我要检查潜在的错误解决方案。我创建了一个同步冲突(离线数据库存储后在服务器上更改数据并在应用程序上更改了一些内容并开始刷新)。
如文档中所述,我可以在 ErrorArchive 中看到错误,还可以看到一些详细信息。但是我缺少的是数据库中 "current" 数据的信息。
在错误详情中我只能看到设备上的数据,但看不到服务器上更改的数据。
例如:
- 设备正在将一些名称加载到离线商店
- 设备离线
- 用户 A 正在更改一些名称
- 用户 B 正在直接在线更改其中一个名字
- 用户 A 再次在线并开始同步
- 用户 A 现在通知已更改的实体但是:
- 不是用户B输入的内容
我刚看到 "offline" 数据。
有没有一种解决方案可以在一种比较视图中查看 "current" 和 "offline"?
另请注意,服务器通信是由 Kapsel 插件完成的,而不是通过正常的 AJAX 调用。这可能是一种替代方法,但我想知道是否没有 API?
支持的更智能的方法与此同时,我想出了如何加载在线数据(手动)。 这可以通过将 http 处理程序切换回普通处理程序来完成。
sap.OData.removeHttpClient();
sap.OData.applyHttpClient();
无论如何,这看起来不是一个合适的解决方案,我也有冲突日志本身的问题。必须先删除它,然后才能应用任何刷新。
我找不到任何合适的文档。 SAPUI5 和 SAP Kapsel 文档中也几乎没有描述 ETag 处理。
默认解决方案是SMP 或HCPms 通过ETag 检测错误。在客户端,没有 API 可以在发生冲突时操纵 ETag。在设备上实现一种差异视图的潜在解决方案如下所示:
- 显示错误
- 缓存错误(可能只在内存中?)
- 删除错误
- 刷新数据库
- 使用当前数据和缓存的错误构建差异视图
想法
sap.OData.removeHttpClient();
sap.OData.applyHttpClient();
也可以工作,但可能非常棘手并且可能会产生副作用。 也许某些请求是针对 "wrong" 后端触发的。
由于其含义,这个问题真的很棘手。我了解到您正在模拟由于并发修改而导致的同步错误,并且想知道客户端是否有办法获取“当前”服务器状态,以便为用户提供一种比较本地和服务器状态的方法。
首先,让我给你一个简短的回答:不,当出现同步错误时,客户端无法通过离线API“参考”当前服务器状态。如上所述进行在线查询可能可行,但这肯定是个坏主意。
现在是更长的答案,这解释了为什么这不一定是缺陷以及为什么我说答案有很多含义。
同步错误的类型
We distinguish a number of synchronization errors,在这种情况下,我们显然是在处理与业务相关的问题。这里有两个子类型:用户可以更正的子类型,例如验证错误,以及业务流程本身的问题。
如果用户超出输入范围,例如通过为产品设置负价格,服务器将回复相应的消息:“-1 不是 'Price' 的有效输入值”。作为开发人员,您可以从错误存档中向用户显示此类消息,随后的修复确实非常简单。
现在,当我们谈论并发修改时,事情变得非常非常糟糕。事实上,我想说,在这种情况下,业务流程存在问题,因为一方面,我们允许数据不同步。另一方面,该过程允许多个用户操纵同一条信息。现在应该如何通知和同步所有相关用户,不再只是一个技术细节,而是一个新的业务流程。只是没有办法通用地设计如何处理这种情况。在大多数情况下,这将涉及需要决定如何合并更改的后台专家。
更好的解决方案
Angstrom 指出没有办法在客户端操作 ETag,事实上你甚至不应该考虑它。 ETag 在乐观锁定场景中的工作方式类似于版本号,更改 ETag 基本上意味着“只是覆盖服务器上的内容”。在严重的情况下这是不行的。
可接受的解决方法如下:
- 确保服务器 returns 详细的错误消息,以便用户可以看到发生了什么以及导致冲突的原因。
- 如果这没有帮助,请刷新数据。这将为您提供更新的 ETag,并将本地更改合并到“当前”服务器状态,但仅限于本地。 “合并”实际上意味着本地更改总是覆盖远程更改。
- 用户现在有另一个机会查看数据并可以再次提交。
一个好的解决方案
更好不一定好,所以这是你真正应该做的:永远不要让并发修改发生,因为处理它真的很昂贵。这意味着开发人员不应该解决此问题,但业务需要更改流程。
正确的问题是,“当您在分布式系统中复制数据时,为什么要允许同时修改它?”通常利益相关者不会喜欢这类问题,适当的反应是与他们一起制定冲突解决流程。只有到那时,他们才会意识到修复这种不同步的成本是多么高昂,而且他们通常会发现调整流程比坚持另一个后台流程来解决它引起的问题要便宜得多。即使他们坚持认为需要进行这种并发修改,他们现在也会明白解决这个问题不是你的任务,他们需要投资解决冲突的过程。
TL;DR
无法将服务器和客户端状态与客户端上的服务器状态进行比较,但您可以进行刷新以保留本地更改并获取更新的 ETag。然而,真正的解决办法是重做业务流程,因为这不再是一个纯粹的技术问题。