xrm sdk带回滚的ExecuteMultipleRequest事务

时间:2017-04-04 22:41:35

标签: dynamics-crm crm

我需要添加大量记录到CRM数据库。

我使用以下代码:

var emRequest = new ExecuteMultipleRequest {
    Requests = entityCreateRequests,
    Settings = new ExecuteMultipleSettings
    {
        ContinueOnError = true,
        ReturnResponses = true
    }
};
var createResponse = (ExecuteMultipleResponse)serviceProxy.Execute(emRequest);

由于记录数量很大,我必须将entityCreateRequests的总数分成500个批次。现在我知道如果500个批次中的一个失败,整个批次都会失败,对我有好处。 但是,我想为我的所有记录做一笔交易,即使我必须一个接一个地做。与实体框架中的事务类似的东西,如:

serviceProxy.begin();
for (i =0 ; i<totalTrans; i++) {
    try {
        var createResponse = (ExecuteMultipleResponse)serviceProxy.Execute(emRequest);
    }
    catch(e) {
        serviceProxy.rollback();
        break;
    }
    serviceProxy.commit();
}

非常感谢任何反馈。

2 个答案:

答案 0 :(得分:2)

您可以(也可能应该)使用未绑定的操作来处理创建。例如,你可以有一个Action'CreateMultipleAccounts',它有一个EntityCollection作为Input参数。

在此Action中,您需要一个迭代EntityCollection并创建记录的工作流程序集。您也可以在此工作流程程序集中执行ExecuteMultipleRequest。

最大的好处是,Actions作为单个事务执行,这意味着如果创建/更新失败,整个过程将被回滚。

确保选中启用回滚复选框。

编辑:Aileen Gusni有一篇博客文章描述了这个实际场景和她的测试结果,你可以在https://community.dynamics.com/crm/b/misscrm360exploration/archive/2015/07/05/utilizing-crm-custom-action-for-transaction-rollback-purposes找到它。

答案 1 :(得分:1)

如果我理解正确,您基本上想要将多个ExecuteMultipleRequests链接到一个请求。我不认为你的想法是可能的。

然而,您可以更新MaxBatchSize,请参阅此处:How to change the default ExecuteMultipleRequest batch size limit in CRM 2011 on premise?

或者在创建时,您可以存储结果并通过在以后的请求失败时删除它们来手动恢复创建。

   
var idList = new List<Guid>();
var emRequest = new ExecuteMultipleRequest
{
    Requests = new OrganizationRequestCollection(),
    Settings = new ExecuteMultipleSettings
    {
        ContinueOnError = false,
        ReturnResponses = true
    },
};

var executeMultipleResponse = (ExecuteMultipleResponse)service.Execute(emRequest);
if (!executeMultipleResponse.IsFaulted)
{
    foreach (var response in executeMultipleResponse.Responses)
    {
        if (!response.Response.Results.Contains("id"))
            continue;

        var idValue = (string)response.Response.Results["id"];
    }
}
else
{
    foreach (var id in idList)
    {
        service.Delete("entitylogicalname", id);
    }
}