У меня есть настраиваемая сущность, которая обновляется почти в реальном времени (около 1000 обновлений в минуту). Поскольку одна и та же запись объекта может обновляться в разных запросах пакетного обновления, а запросы принимаются из разных асинхронных источников, есть вероятность, что более недавнее обновление в CDS может быть перезаписано более старым обновлением.
- Обновление 1 (с настраиваемым атрибутом datamodifiedon, установленным на 8.02 PM) для записи Entity A обрабатывается асинхронной службой S1.
- Обновление 2 (с настраиваемым атрибутом datamodifiedon, установленным на 8.03 PM) для записи Entity A обрабатывается асинхронной службой S2.
Из-за задержки в сети или по какой-либо другой причине служба S1 работает немного медленнее, а служба S2 продолжила и запустила свой вызов обновления для записи Entity A с измененными данными в 20.03.
Сервис-1 теперь запускает Обновление-1 для той же записи объекта, и обновление, произошедшее в 20.03, перезаписывается обновлением, произошедшим в 20.02, что приводит к потере данных.
Я зарегистрировал плагин для сообщения Update SDK моего настраиваемого объекта на этапе 10 (предварительная проверка). Этот плагин сравнивает атрибут datamodifiedon из входных параметров с атрибутом, установленным в изображениях пред-сущностей из контекста плагина. И выдает исключение Invalid Plugin Execution, если изображение до объекта уже имеет более свежий атрибут datamodifiedon.
// 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. Обновление-2 (данные, измененные в 20.03) находится на стадии предварительной проверки. После успешной проверки, актуальное обновление в базе данных выполняется. 2. Теперь Update-1 переходит в стадию предварительной проверки. Поскольку Обновление-2 еще не зафиксировано в базе данных, будет ли изображение пред-сущности, полученное на этом этапе, по-прежнему старым значением и позволит ли пройти проверку?
Поможет ли регистрация этого плагина на этапе Pre-Operation или Post-Operation вместо этапа Pre-Validation, поскольку два других этапа выполняются в одной транзакции базы данных?
Есть ли другой способ решить эту проблему параллелизма? Поскольку обновление инициируется пакетным вызовом odata, предварительное условие eTag не может использоваться в заголовке запроса.