Personalized Community is here!
Quickly customize your community to find the content you seek.
Choose your path Increase your proficiency with the Dynamics 365 applications that you already use and learn more about the apps that interest you. Up your game with a learning path tailored to today's Dynamics 365 masterminds and designed to prepare you for industry-recognized Microsoft certifications.
Visit Microsoft Learn
2021 Release Wave 1Discover the latest updates and new features to Dynamics 365 planned April 2021 through September 2021.
Release overview guides and videos Release Plan | Preview 2021 Release Wave 1 Timeline
The FastTrack program is designed to help you accelerate your Dynamics 365 deployment with confidence.
FastTrack Program | Finance and Operations TechTalks | Customer Engagement TechTalks | Upcoming TechTalks | All TechTalks
We have an existing 'AutoNumbering' plugin running on create entity X that needs to increment a counter that is stored in entity Y and add the content to a field in entity X
The plugin is using a critical section (2 to 7 below) in order to avoid race conditions.
1 enter plugin for entity x
2 enter critical section (Mutex)
3 retrieve the counter from y
4 increment counter
5 update counter in y
6 set entity x's field = counter
7 Exit critical section (Mutex)
8 leave the plugin
The scenario above does not work correctly when concurrent clients call Create x. We sometimes get duplicate values in entity X
We kind of figured out that the update (5) does not execute until later when the threads leaves the plugin (8), but this is too late because a context switch already occurred and the next client is reusing the value counter that has not been saved yet.
Is there a way to call (3) and (5) using the SDK with a different transaction?
You can greatly optimize this process by adding a plugin on Retrieve Multiple Entity Y.
To call the first record in plugin X from entity Y (of course with a special field in Column Set that is checked in plugin Y so that this plugin does not always run and only run if it is from this source)
In the plugin on Y, which is written on the Post Operation stage, you add the record that was called to the count field and save the result in Y, and return the same result to plugin X.
In this way, you only use this returned field in Plugin X, and creating multiple records at the same time does not disrupt this process.
Thanks for your answer. I think that I understand the idea. This is pretty smart.
I will try to prototype it and update this post when I have a solution.
Try using the lock statement in your plugin code, this way, if subsequent calls arrive and the code is already executing, they will be queued until the lock is released. This is a link on how the lock statement works: docs.microsoft.com/.../lock-statement
Yes, I am using a lock between 2) and 7) I called it 'Mutex', which is the same.
The problem is that the save in 5) is not executed right away, but only when the plugin commit the transaction and exits, so the subsequent call will read the same value of the counter in 3).
Did you register the plugin on preoperation or postoperation?
Pre-validation since we want to update the autoNumber field in the entity when creating.
Are you working with d365 on premise or online? If it is on-premise, is it a NLB environement or not? Bcz if it is not a NLB environement the lock should work well if it is implemented
We are running onPremise without LB.
The lock works perfectly well. I can see that with the debugger. The problem is that within a plugin, there is only one transaction and it is committed at the end of the plugin.
i.e. the call to
service.Update(y); (at line 5 in the pseudo code)
is not executed right away, but when the DB transaction commits at the end of the plugin i.e. after the locked section has terminated at line 8)
Plz register your plugin in preoperation and not on prevalidation bcz the preoperation is inside the transaction and try.
I will try that and update the post with the results. Thanks
I have tried the 4 different combinations of those 2 variants and this is what I have noticed
Here are the results i.e. whether the sdk call Update(x) saves to the DB or not
1 Pre-validation + sdk saves to the DB right away
2 Pre-operation + sdk does not save to the DB right away (*)
3 Pre-validation + workflow does not save "
4 Pre-operation + workflow does not save "
(*) i.e. saves to the db once the plugin has finished executing
I also read that he calls from the workflow do not have a transaction, so I am surprised that the sdk does not save to the db right away. Kind of strange.
1 and 2 makes sense because there is a transaction in 2 only
3 and 4 don't make sense
Normally the Pre-Operation will properly work within the transaction (I have done it many times).
Here is a link for more details about the event pipeline of a plugin : carldesouza.com/.../
For the concurrent users' calls, try to put all the plugin logic inside the lock statement and test.
Business Applications communities