Dynamics CRM中的操作(action)是否是一个事务(transaction)?
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复168或者20151104可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me!
以前的博文 微软Dynamics CRM 2013介绍系列之二十三:操作(Action)的开发与配置 简单介绍了Dynamics CRM 2013起新增一种新的流程类型--操作,英文是action,没有做实验证实,操作中所有的步骤是否是同一个事务?是否存在可选的选项?如果不是的话,Microsoft Dynamics CRM Online 2015 Update 1 的更新中包括了一个新的消息叫做 ExecuteTransactionRequest 用来在同一个事务中执行多个消息应该是个补充,我因为没有CRM Online 2015 Update 1环境,而Dynamics CRM 2015本地部署的版本又一直没有出Update 1功能包,所以暂时无法演示给这个消息给大家看。相信待到今年出来Dynamics CRM 2016出来后是可以演示的。
在解决方案中,我们建立一个简单的流程,如下:我这里选择的实体是 无(全局) ,这样执行起来方便点。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img0.ph.126.net/FrA7w5SIoWO96_lb6Ngq8A==/6630540000119304900.png)
我先增加两个简单的字符串类型的参数如下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/x2PDwLqYoGqoNoIhCvscUA==/6630483925026284210.png)
我这里增加两个简单的类型为 创建记录 的步骤,步骤一创建的客户为本操作的参数AccountName1的值,步骤二创建的客户为本操作的参数 AccoutName2 的值。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/4TMJBg_GqGfGXr9Lg565xg==/6630145275444933533.png)
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/QpitgsFCSpANDSrXa2x12w==/6630076006212379928.png)
我目前阶段只能通过代码来调用这个操作。因为在Dynamics CRM 2015中还不支持直接在工作流中调用操作,而到了Dynamics CRM 2015 Update 1则支持了。代码如下:
static void Main(string[] args) { var service = GetOrganizationService(); var whoAmIReq = new WhoAmIRequest(); var whoAmIResp = service.Execute(whoAmIReq) as WhoAmIResponse; OrganizationRequest req = new OrganizationRequest("new_TestAction"); req["AccountName1"] = "测试创建的客户一"; req["AccountName2"] = "测试创建的客户二"; req["Target"] = new EntityReference("systemuser", whoAmIResp.UserId); service.Execute(req); Console.WriteLine("程序运行完成!"); Console.ReadKey(); }
运行代码后真的创建了两个客户如下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/FXiz21IevqwTcHitXHpSbw==/6631361335305106054.png)
为了测试我将这两个新建的客户删除,然后我在创建客户时间上注册了一个实时工作流来让创建客户产生异常:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/JwTkUGzR4T7oK350qoGFZw==/6630445442119313086.png)
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img0.ph.126.net/5maCYJsR9NPbtjwsL91w8g==/6630516910375115679.png)
激活工作流以后,如果我手工创建客户名称包括 二 的客户会报错如下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/I8IwhHmLczBnuq21DXDGNA==/6631351439700461998.png)
当然用代码来执行也会报错,我还是执行前面的代码,代码会跑出异常如下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/K_nRPgaPjK8mQ8w30co3iQ==/6630776395119998152.png)
这个时候我去刷新下客户界面看看第一个步骤增加的 测试创建的客户一 是否增加,发现没有增加。是我的代码没有处理异常吗?我用异常处理块将代码包括起来还是同样的错误。看来至少两个CRM操作是在同一个事务中。
细心的朋友可能会发现,定义操作的时候有个选项默认是选中的,那就是启用回滚选项,如下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img0.ph.126.net/FsUrdj2g7TRdjavadLx7Ng==/6631343743119067737.png)
所以我在想,如果我去掉这个选中,也就是不选中 启用回滚 ,会不会就不在同一事务中了?于是我这样修改后激活去测试下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/-rxhX4i-QVvIyg_pZReaRw==/6631415211374866244.png)
然后我去执行前面相同的代码,结果是创建了 测试创建的客户一,没有创建 测试创建的客户二 ,看来是没有回滚,也就是这个选项还是很重要的。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/BiOBnkPN5QN9CPcpN4uoGg==/6630278316351893633.png)
我们继续做一个小实验,就是在前面两个步骤以后加一个调用自定义工作流活动的步骤,这个自定义工作流活动我只是简单的下载一个链接的文件作为第二个客户的附件而已,代码如下:稍微注意下,如果输入类型是EntityReference,需要通过ReferenceTarget属性指定是那个实体。
public sealed class GetNoteContent : CodeActivity { [RequiredArgument] [Input("要添加附件的客户")] [ReferenceTarget("account")] public InArgument<EntityReference> InAccount { get; set; } protected override void Execute(CodeActivityContext executionContext) { IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>(); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); try { // TODO: Implement your custom Workflow business logic. using (WebClient client = new WebClient()) { byte[] responseBytes = client.DownloadData(@"http://www.luoyong.me/GetAnnotationDocument.ashx?AnnotationId=B39F0691-C377-E511-80ED-000D3A800514"); var annotationEntity = new Entity("annotation"); annotationEntity["documentbody"] = Convert.ToBase64String(responseBytes); annotationEntity["subject"] = "微软MVP罗勇用代码增加的带附件的注释标题"; annotationEntity["notetext"] = "微软MVP罗勇用代码增加的带附件的注释内容"; annotationEntity["filename"] = "附件.pdf"; annotationEntity["mimetype"] = "application/pdf"; annotationEntity["isdocument"] = true; annotationEntity["objectid"] = InAccount.Get(executionContext); service.Create(annotationEntity); } } catch (FaultException<OrganizationServiceFault> e) { tracingService.Trace("Exception: {0}", e.ToString()); // Handle the exception. throw; } tracingService.Trace("Exiting GetNoteContent.Execute(), Correlation Id: {0}", context.CorrelationId); } }
同时我还禁用然后删除了之前创建的自定义工作流,这样创建第二个客户才能成功。修改了测试的操作,增加了一个调用自定义工作流活动的步骤如下:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img0.ph.126.net/tlyxOTmYWG9_P-5MStuj2A==/6597247887542615556.png)
我先测试 启用回滚的情况,测试结果发现两个客户创建成功,且第二个客户也增加了附件。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img0.ph.126.net/EZvQAtvIfQpmuQcZ4onVsA==/1320399115767814779.png)
正常的能成功,我就稍微修改下自定义工作流活动的代码,故意把URL搞错,然后测试,抛出了如下异常:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/Xmfim1OJVSn3qwXKaB2tUg==/6631406415281857558.png)
然后我们去看创建的客户,发现没有创建客户。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/QcAI0uPqziHn5YlU2dXwug==/6608867526423170351.png)
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img0.ph.126.net/t16V90eO57925UiP__ITyw==/1052997887892942219.png)
然后我还测试下,将这个创建附件的步骤放到第二步,且是为第一个创建的客户添加附件:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/7jcsI2vzhhy437R9o_dJYQ==/6631275573398156848.png)
当没有选中 启用回滚 选项的时候测试结果是:客户一创建成功,第二个步骤出错,没有回滚整个操作,第三个步骤没有执行。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/IvyOoErI7Zw0EcOvsciG-Q==/6630461934793737754.png)
如果我选中 启用回滚 选项的话,测试结果是回滚了整个操作所做的事情。
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/NtnNKt7OKY1SH6KGkl9rgg==/1064538361938084077.png)
所以稍微总结下就是,操作如果选中了 启用回滚 这个选项,操作的所有步骤都是一个事务,如果没有选中,则是成功的会commit,失败的当然失败,后面的步骤不会执行。可以用来保证一次多个操作的事务性。
当我要删除创建的测试工作流活动的时候,又碰到使用SDK的插件注册工具(PluginRegistration)删除自定义工作流活动的时候登陆以后出现空白的情况,按照帖子 CRM SDK 2015 Plugin registration tool not working 的说法,是语言包的问题,我得解决办法就是把插件注册工具文件夹中的除了 en, en-us 文件夹外所有的语言包都删除掉:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img2.ph.126.net/l5rgB7qu-zMUsGKHVB8Ieg==/6631233791956303145.png)
当然还可以用Developer Toolkit来删除,如下,自己再删除源文件和 RegisterFile.crmregister 文件中的相应内容即可:
![Dynamics CRM中的操作(action)是否是一个事务(transaction)? - 罗勇 - 微软MVP-罗勇的博客](http://img1.ph.126.net/B5EJHZf7GuBrO1-JOzUs4w==/6619266707398900465.png)