【发布时间】:2017-12-07 17:46:35
【问题描述】:
在使用 Dynamics365 Sdk 将数据写入 Dynamis CRM 数据库中的自定义实体 new_licenseRecordsSet 时,我遇到了一些并发问题,有时会在目标表中创建完全重复的记录。如下所示的检查现有记录的代码(并仅在现有记录为空时创建新许可证)似乎并不总是有效(在 98% 的时间内它确实有效)。
private LicenseRecDto GetExistingLicRecord(int accountId, short instanceId, int licenseId, IOrganizationService service)
{
var context = new DynamicsCrmProxyContext(service);
var dynamicsExpectedInstanceId = (Int32)instanceId; // Dynamic sdk will throw exception of not casting a short; weird but true
//In some rare cases we found there were exact duplicates of same License record in Dynamics CRM. Using FirstOrDefault instead of SingleOrDefault will avoid throwing unnecessary exception and
//make the same record got created again and again in Dynamics.
var license = context.new_licenseRecordsSet
.Where(
l => l.new_LicenseID == licenseId
&& l.new_InstanceID == dynamicsExpectedInstanceId
&& l.new_AccountId == accountId)
.OrderByDescending(d => d.VersionNumber)
.FirstOrDefault();
return license?.MapToDynamicsObject<LicenseRecDto>();
}
private void CreateUpdateLicense(LicenseRecDto license, IOrganizationService service)
{
var dynamicsLicense = GetExistingLicRecord(license.AccountId, license.InstanceId, license.LicenseId, service);
if (dynamicsLicense != null)
{
license.DynamicsLicenseGuid = dynamicsLicense.DynamicsLicenseGuid;
UpdateLicense(license, service);
}
else
{
var result = CreateLicense(license, service);
if (result != Guid.Empty)
license.DynamicsLicenseGuid = result;
}
}
不确定为什么此检查在 2% 的时间内失败,并且仍然在 new_licenseRecordsSet 中创建了完全相同的重复记录,我决定在目标表上创建唯一索引,其中包括以下三列:LicenseId、AccountId 和 InstanceId。但我将如何进行?我们的 DBA 不允许在 SQL Server 的架构中进行任何更改,我无法从 Dynamics CRM UI 中找到任何其他方式来让我在自定义实体上添加唯一约束。
我的问题:
- 在检查现有记录时可能导致代码失败的原因是什么?我的猜测是可能有两个并发线程同时检查同一记录并且都返回 null 并且都导致创建新记录。如果是这种情况,我该如何施加锁定以避免并发检查?
- 关于在自定义 new_LicenseRecords 表上创建唯一索引,最好的方法是什么?有 SDK 方法吗?我搜索了一下,目前没有找到。
提前致谢。
【问题讨论】:
标签: dynamics-crm unique-index xrm