【发布时间】:2019-11-22 15:53:00
【问题描述】:
我有一个自定义实体,它具有近乎实时的更新(每分钟大约 1000 次更新)。由于同一实体记录可能在不同的批量更新请求中得到更新,并且请求是从不同的异步源接收的,因此 CDS 中较新的更新可能会被稍旧的更新覆盖。
- 实体记录 A 的 Update-1(自定义属性 datamodifiedon 设置为 8.02 PM)由异步服务 S1 处理。
- 实体记录 A 的 Update-2(自定义属性 datamodifiedon 设置为 8.03 PM)由异步服务 S2 处理。
由于网络延迟或其他原因,S1 服务稍微慢了一点,服务 S2 继续并在晚上 8 点 3 分对实体记录 A 进行了更新调用。
Service-1 现在在同一实体记录上触发 Update-1,并且发生在 8.03PM 的更新被发生在 8.02PM 的更新覆盖,从而导致数据丢失。
我在第 10 阶段(预验证)为我的自定义实体的更新 SDK 消息注册了一个插件。 此插件将来自输入参数的 datamodifiedon 属性与来自插件上下文的 pre-entity 图像中的一组进行比较。 如果前实体图像已经具有更新的 datamodifiedon 属性,则抛出 Invalid Plugin Execution 异常。
// If ModifiedOn value in pre-image is later than the one received in input parameters, this is an obsolete request and must be rejected.
if (preImage.Contains("datamodifiedon")
&& preImage.GetAttributeValue<DateTime>("datamodifiedon") != DateTime.MinValue
&& entity.Contains("datamodifiedon")
&& entity.GetAttributeValue<DateTime>("datamodifiedon") != DateTime.MinValue
)
{
if (DateTime.Compare(preImage.GetAttributeValue<DateTime>("datamodifiedon"), entity.GetAttributeValue<DateTime>("datamodifiedon")) > 0)
{
string traceMessage = "PreOperationLiveWorkItemUpdatePlugin: Update request is obsolete. datamodifiedon field found in pre-entity image: "
+ preImage.GetAttributeValue<DateTime>("datamodifiedon")
+ "datamodifiedon field in Input parameters: "
+ entity.GetAttributeValue<DateTime>("datamodifiedon");
tracingService.Trace(traceMessage);
throw new InvalidPluginExecutionException(traceMessage);
}
}
由于更新非常频繁,是否有可能 1. Update-2 (datamodifiedon 8.03 PM) 处于预验证阶段。验证成功后,数据库中的实际更新正在进行中。 2. 现在Update-1 进入预验证阶段。由于 Update-2 还没有提交到数据库中,在这个阶段接收到的 pre-entity 图像是否仍然是旧值并让验证通过?
由于其他两个阶段在同一个数据库事务中执行,因此在 Pre-Operation 或 Post-Operation 阶段注册此插件是否会有所帮助而不是 Pre-Validation 阶段?
还有其他方法可以解决这个并发问题吗?由于更新是通过批量 odata 调用启动的,因此无法在请求标头中使用 eTag 前置条件。
【问题讨论】:
标签: plugins dynamics-crm microsoft-dynamics dynamics-crm-online concurrentmodification