Dynamics CRM 插件是在数据库事务内部还是外部注册为 "post operation" 运行?

Are Dynamics CRM plugins registered as "post operation" run inside or outside the DB transaction?

我正在为 Dynamics CRM(2015 和 CRM Online)的自定义 C# 插件注册插件。

当您使用 Visual Studio CRM Explorer 创建新插件时,您会看到标准的 "Create Plug-in" 对话框:

"Pipeline Stage"下有3个选项:

  1. 预验证
  2. 运营前
  3. Post-运算

在此处选择 Post-Operation 会将此代码添加到 XML 注册文件中:

    <Plugin Description="..." FriendlyName="PostContactCreate" Name="Cacheron.PostContactCreate" Id="00000000-0000-0000-0000-000000000000" TypeName="Cacheron.PostContactCreate">
      <Steps>
        <clear />
        <Step CustomConfiguration="" Name="PostContactCreate" Description="Post-Operation of Contact Create" Id="00000000-0000-0000-0000-000000000000" MessageName="Create" Mode="Synchronous" PrimaryEntityName="contact" Rank="1" SecureConfiguration="" Stage="PostOutsideTransaction" SupportedDeployment="ServerOnly">
          <Images />
        </Step>
      </Steps>
    </Plugin>

关键部分是那条中间线,上面写着Stage="PostOutsideTransaction"

该工具生成的相应 C# 代码包括以下行:

base.RegisteredEvents.Add(
  new Tuple<int, string, string, Action<LocalPluginContext>>(
    40, 
    "Create", 
    "contact", 
    new Action<LocalPluginContext>(ExecutePostContactCreate)
  )
);

插件注册中的神奇数字 40 似乎对应于 https://msdn.microsoft.com/en-gb/library/gg327941.aspx 中记录的 "pipeline stages",即

Post-Event

Post-operation

40

Stage in the pipeline for plug-ins which are to execute after the main operation. Plug-ins registered in this stage are executed within the database transaction.

所以我得到了由工具生成的注册 XML,上面清楚地写着 PostOutsideTransaction,而 C# 代码是由指定的同一工具生成的第 40 阶段,即 "executed within the database transaction"

那是哪一个? XML 注册语法是否使用了误导性名称,或者这是插件创建工具中的错误,还是执行管道做了一些我不明白的聪明事?

40肯定是post-操作和内交易。您可以很容易地看出是这种情况,因为如果您的第 40 阶段插件步骤抛出异常,则触发插件的整个操作都会回滚。

顺便说一句,我强烈建议放弃 SDK 中的开发人员工具包。由于多种原因,它有很多问题并且非常烦人。我强烈推荐免费和开源 CRM Developer Extensions,它更好。

这取决于您的 post 操作插件步骤注册的消息。对于最常见的消息,该步骤在数据库事务中执行:

  • Create
  • Update
  • Delete
  • SetState
  • Assign

其他一些消息可能会在数据库事务之外执行,例如PublishPublishAll,对于其他情况则有所不同(RetrieveRetrieveMultiple)。

IPluginExecutionContext 对象中,您可以检查 IsInTransaction 属性。