Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CRM 2011 SDK transaction

How to create transaction using crm 2011 sdk and XrmServiceContext?

In next example 'new_brand' is some custom entity. I want to create three brands. Third has wrong OwnerID guid. When I call SaveChanges() method, two brands are created and I've got exception. How to rollback creating of first two brands?

Is it possible without using pluggins and workflows?

using (var context = new XrmServiceContext(connection))
{
    SystemUser owner = context.SystemUserSet.FirstOrDefault(s => s.Id == new Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));

    // create 3 brands
    new_brand b1 = new new_brand();
    b1.new_brandidentification = 200;
    b1.new_name = "BRAND 200";
    b1.OwnerId = owner.ToEntityReference();
    context.AddObject(b1);

    new_brand b2 = new new_brand();
    b2.new_brandidentification = 300;
    b2.new_name = "BRAND 300";
    b2.OwnerId = owner.ToEntityReference();
    context.AddObject(b2);

    new_brand b3 = new new_brand();
    b3.new_brandidentification = 400;
    b3.new_name = "BRAND 400";
    b3.OwnerId = new EntityReference(SystemUser.EntityLogicalName, new Guid("00000000-0000-0000-0000-000000000000"));
    context.AddObject(b3);

    context.SaveChanges();
}
like image 209
lazarus Avatar asked Jun 14 '12 07:06

lazarus


People also ask

What is Microsoft XRM SDK messages?

Microsoft. Xrm. Sdk. Messages Microsoft. Xrm. Sdk. Messages Contains the data that is needed to execute one or more message requests in a single database transaction, and optionally return a collection of results. This message works regardless whether the caller is connected to the server or offline.

How are Microsoft Dynamics CRM 2011 plug-ins triggered?

By default, Microsoft Dynamics CRM 2011 plug-ins that are triggered by the same event run within the same SQL Server database transaction, as do any related calls to the SDK. For example, both the creation of an account and a subsequent call to the SDK to generate a related task to welcome the customer would be included in a single transaction.

Why does Microsoft Dynamics CRM not take out a read lock?

As a result of the database hints indicating to SQL Server not to take out a read lock during these common retrieve requests, queries of Microsoft Dynamics CRM occurring via the web service are unlikely to trigger this type of lock under normal conditions.

How do I enable auditing in CRM 2011?

Enabling Auditing. Before auditing can be used in CRM 2011 you will need to enable it at the system level. You can enable auditing from Settings -> Auditing -> Global Audit Settings or Settings -> Administration -> System Settings. On the Auditing tab you will be able to check the box next to Start Auditing to enable audit functionality.


3 Answers

Actually this is possible without the use of Plugins.

You can use CRM relationship links to force transactional behaviour:

EntityA primaryEntity = new EntityA() { //initialise me... };
EntityB secondaryEntity = new EntityB() { //initialise me... };

context.AddObject(primaryEntity);
context.AddObject(secondaryEntity);

// This is the key part: explicitly link the two entities
context.AddLink(primaryEntity, 
    new Relationship("relationship_name_here"), secondaryEntity);

// commit changes to CRM
context.SaveChanges();

There are a few drawbacks to this approach:

  • Obviously, a relationship must exist in CRM between the two entities. If no relationship exists you will have to go with a plugin.
  • I personally find the code can become messy if you need to save a large hierarchy of objects all in one go.

An alternative approach might be to consider implementing a command pattern using plugins.

The idea is that you create the CRM objects on the client, serialize them and pass them to CRM via a custom entity. A pre-create plugin is then set-up on this entity to de serialize and create the objects within the plugin transaction scope.

An excellent blog post describing both strategies can be found here: http://crm.davidyack.com/journal/2012/6/26/crm-client-extension-data-access-strategies.html

like image 77
tswann Avatar answered Oct 12 '22 00:10

tswann


The only support CRM provides for transactions is within a plugin, and I don't even believe that will help you in this case, since each creation of a brand, will take place in its own transaction.

The easiest way I can think of to implement this sort of logic is adding a new field to new_Brand called new_TransactionGroupId, and use it to delete any records that were created like so:

using (var context = new XrmServiceContext(connection))
{
    SystemUser owner = context.SystemUserSet.FirstOrDefault(s => s.Id == new Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"));
    var transactionGroupId = Guid.NewGuid();

    // create 3 brands
    new_brand b1 = new new_brand();
    b1.new_brandidentification = 200;
    b1.new_name = "BRAND 200";
    b1.OwnerId = owner.ToEntityReference();
    b1.new_TransactionGroupId = transactionGroupId ;
    context.AddObject(b1);

    new_brand b2 = new new_brand();
    b2.new_brandidentification = 300;
    b2.new_name = "BRAND 300";
    b2.OwnerId = owner.ToEntityReference();
    b2.new_TransactionGroupId = transactionGroupId ;
    context.AddObject(b2);

    new_brand b3 = new new_brand();
    b3.new_brandidentification = 400;
    b3.new_name = "BRAND 400";
    b3.OwnerId = new EntityReference(SystemUser.EntityLogicalName, new Guid("00000000-0000-0000-0000-000000000000"));
    b3.new_TransactionGroupId = transactionGroupId;
    context.AddObject(b3);

    try{
        context.SaveChanges();
    } catch (Exception ex){
        // Since one brand failed, cleanup all brands
        foreach(brand in context.new_brand.where(b => b.new_TransactionGroupId == transactionGroupId)){
            context.Delete(brand);
        }
    }
}
like image 23
Daryl Avatar answered Oct 11 '22 23:10

Daryl


Is it possible without using plugins and workflows?

No I don't believe that it is. Each context.AddObject() is atomic. If you don't want to use plug-ins then all I think you can do is have some sort of clean-up logic that deletes the created records if your conditions are not met.

like image 1
Greg Owens Avatar answered Oct 11 '22 23:10

Greg Owens