Experience your
30 day trial
now!
GET STARTED
New to Microsoft Dynamics CRM 4 is the concept of having a single windows service that will manage all asynchronous operations. Each time an asynchronous operation takes place a number of log entries are created in the tables that support asynchronous operations.
Some examples of asynchronous operations are:
The logged information is great for tracking system jobs and workflows but can contribute to a large CRM organization database. For instance, every 5 minutes CRM generates matchcodes for duplicate detection rules to keep duplicate detection current. A log record is created for each one of the entities, if you had 3 entities with duplicate detection rules there would be 864 matchcode log entries per day (1440 minutes / 5 minutes * 3).
So, now you’re asking, “what can I do to control this or clear these out?”. You can use the Bulk Delete feature ( http://msdn.microsoft.com/en-us/library/cc155955.aspx) as documented in the CRM SDK. You can issue bulk deletes for out of the box and custom entities which includes the AsyncOperation entity otherwise known as the “System Job” entity. The bulk delete operation takes as input a QueryExpression and deletes the records returned by the query. Any QueryExpression you write could be used as part of a bulk delete. After creating the bulk delete job CRM will execute the deletes one after the other (the deletes are not set based) each delete will be evaluated against the business logic in the system just as if you were deleting records in the application. This means that any plugins you’ve registered will fire, cascading will occur, etc. It also means that the delete jobs may take some time to process before all the records are cleared out.
There are some prerequisites when trying to delete asyncoperation records using bulk delete.
Keeping those items in mind we should only include completed records and for this example we’ll also exclude any workflow operations. The sample can be altered to specifically delete match code jobs or include workflow operations, the sky is the limit. However, be careful with this sample be sure to test your bulk delete in an environment where you can monitor the deleted data, you should test your QueryExpression before issuing a BulkDelete to be sure that it is returning the correct data. A fully functioning solution / sample can be found at: http://code.msdn.microsoft.com/crmbulkdelete.
The following sample builds off the article written by Mahesh (link). In my sample I’ve included the following helper files provided in the CRM SDK:
Please note that when using these helpers you’ll want to make sure you correct the namespaces in the helper files, for instance if your project namespace is BulkDeleteMessageSample and web service reference is CrmSdk; the namespaces in the helpers should be changed to BulkDeleteMessageSample.CrmSdk.
1: static void runBulkDelete()
2: {
3:
4: CrmAuthenticationToken token = new CrmAuthenticationToken();
5: token.AuthenticationType = 0;
6: token.OrganizationName = "AdventureWorksCycle";
7: CrmService service = new CrmService();
8: service.Url = "http://crmserver/mscrmservices/2007/crmservice.asmx";
9: service.CrmAuthenticationTokenValue = token;
10: service.Credentials = System.Net.CredentialCache.DefaultCredentials;
11: //create a QueryExpression using the helper
12: QueryExpressionHelper expression = new QueryExpressionHelper("asyncoperation");
13: expression.Columns.AddColumn("asyncoperationid");
14: expression.Criteria.Conditions.AddCondition("statecode", ConditionOperator.Equal, (int)AsyncOperationState.Completed);
15: expression.Criteria.Conditions.AddCondition("completedon", ConditionOperator.OlderThanXMonths, 1);
16: expression.Criteria.Conditions.AddCondition("operationtype", ConditionOperator.NotEqual, (int)AsyncOperationType.Workflow);
17: Guid[] emptyRecipients = new Guid[0];
18: //Create a BulkDeleteRequest
19: BulkDeleteRequest request = new BulkDeleteRequest();
20: request.JobName = "Bulk delete completed asyncoperations to free up space";
21: request.QuerySet = new QueryBase[] { expression.Query };
22: request.ToRecipients = emptyRecipients;
23: request.CCRecipients = emptyRecipients;
24: request.SendEmailNotification = false;
25: request.RecurrencePattern = string.Empty;
26: request.StartDateTime = CrmDateTime.Now;
27: BulkDeleteResponse response = (BulkDeleteResponse)service.Execute(request);
28: Console.WriteLine("Bulk delete job with id: {0} has been created", response.JobId);
29: }
Additional notes regarding Bulk Delete jobs:
Cheers,
Sean McNellis
PingBack from http://www.tmao.info/leveraging-bulk-delete-jobs-to-manage-system-job-log-records/
I was conducting a LiveMeeting session with the folks from the CRM User Group at http://www.crmug.com
Is there any way, in which i can schedule a System Job that does stuff for me.
Example:
Create systemjob which every night runs some logic, of my choice. Can I do this?
Thanks :o)
Best regards,
Martin, Denmark.
Hi Sean, thanks for the guidance. We're a CRM hosting provider, and our platform runs hundreds of CRM organizations. Have you any guidance on how to improve async performance and manage system jobs for hundreds of organizations without performaing per-organization programming?
Thanks, Neil
Hi Martin -
Yes you can schedule jobs. Please refer to the additional notes under: Recurrence. I would recommend also downloading the SDK (there is a link in the article) and looking at the recurrence patterns. You can setup jobs to recur daily, weekly, monthly, etc.
Thanks!
Sean
>>It also means that the delete jobs may take some time to process before all the records are cleared out.<<
We're finding the bulk delete to be extremely slow. We have a few tables with relationships but nothing terribly complex. Any tips on getting it to run faster?
Thanks,
Krip