creatiive
creatiive

Reputation: 1093

CRM plugin execution of operations before Exception

I have a plugin that needs to create a bunch of entities, and does so using;

service.Create(Entity);

At the end of the plugin (pre-operation on Update, synchronous) I sometimes need to cancel the save operation. The only way I know how is to throw an exception, but if I do that my service.Create(Entity) does not get executed.

How do I force the service to execute the operations inside the plugin, and then cancel the save by throwing an exception?

EDIT: The code is;

var id = service.Create(newEntity);
throw new Exception("Cancelled Save but created the new entity");

If I throw the exception, the entity does not get created. If I do not throw the exception, the entity does create. I need it to create and also throw the exception so that the save operation is cancelled.

Thanks for any pointers.

Upvotes: 1

Views: 3184

Answers (2)

Josh Painter
Josh Painter

Reputation: 4111

Nicknow's answer is correct, but there are still a few ways to accomplish what you want to do.

  1. In your plugin, don't use the OrganizationService from the plugin context. Create your own new OrganizationService just like you would if you were creating a console app. This new OrganizationService won't be subject to the transaction scope of the original OrganizationService.

  2. Create a web service that does the work. From your plugin, call this web service. The web service won't be subject to the transaction scope of the original OrganizationService.

  3. Use ExecuteMultiple. I've never tried this but here's somebody who claims it works: http://crmtidbits.blogspot.com/2014/02/bypass-plug-in-transaction-to-log.html

Hope that helps!

Upvotes: 2

Nicknow
Nicknow

Reputation: 7224

If IPluginExecutionContext.IsInTransaction == true then when an Exception is thrown anything that has been written to the database will be rolled back. You can try registering in the Pre-Validation stage and sometimes that is outside the transaction, but not always.

Just be aware that there is no guarantee it'll always be outside of the transaction. The SDK documents make this very clear - so at anytime an update could occur that puts it in a transaction.

https://msdn.microsoft.com/en-us/library/gg327941.aspx#bkmk_DatabaseTransactions:

Plug-ins may or may not execute within the database transaction of the Microsoft Dynamics CRM platform. Whether a plug-in is part of the transaction is dependent on how the message request is processed by the pipeline. You can check if the plug-in is executing in-transaction by reading the IsInTransaction property inherited by IPluginExecutionContext that is passed to the plug-in. If a plug-in is executing in the database transaction and allows an exception to be passed back to the platform, the entire transaction will be rolled back. Stages 20 and 40 are guaranteed to be part of the database transaction while stage 10 may be part of the transaction.

Any registered plug-in that executes during the database transaction and that passes an exception back to the platform cancels the core operation. This results in a rollback of the core operation. In addition, any pre-event or post event registered plug-ins that have not yet executed and any workflow that is triggered by the same event that the plug-in was registered for will not execute.

Upvotes: 2

Related Questions