We recently came across a problem with Outlook synchronization with the AX2009 client. The problem was that sometimes when a user synchronized it failed with the error message:

"Cannot edit a record in Activities (smmActivites). An update conflict occured due to another user process deleting the record or changing one or more field in the record."

This could not be reproduced and seemed to be happening in a random way. However we did find a situation that causes this to happen, and a way to prevent it, so if this is happening to you then please read on...

My final repro scenario is this:
- Create an appointment on machine A and synchronize with AX.
- On Machine B, open outlook (it must have been already closed when creating the appointment on machine A) wait for it to see the new appointment. Synchronize with AX.
- The error will be displayed.

The reason that this causes a problem is because Outlook on machine B picks up a different entryId for the person assigned to the appointment. EntryIds are store specific. So what is happening when trying to synchronize with AX is that the process first finds that the existing attendee in AX which has for example entryId=1 (actually this is a crazy guid value, but let's use 1 for this example) is no longer listed on the appointment from Outlook, so it removes them, and it also sees that the attendee was the owner of the appointment so it deletes the smmActivities record - then in the same transaction it find now it has a new attendee for the same appointment with entryId=2 and it tries to add them the appointment and update it - but it has just been deleted so we fail with the error as we try to delete the appointment.

From our investigation this is a limittion of the Outlook synchronization - we have a feature in CRM->periodic->microsoft office outlook synchronization->migrate which allows a user to clear all links with their Outlook so they can migrate to a new OS or a new machine - which shows that this is not expected to synch from multiple different machines at the same time.

Having said that, it was possible in this scenario to change the X++ code to cope with the situation described above, you can add a check, when deciding to delete an attendee during the synchronize, to check whether the related activity has a new owner with the same emplId – if it does then we know we shouldn’t delete it.

In Classes\SmmOutlookSync_Appointment.syncAttendeesOutlookToAxapta()

Existing code:


     // Delete attendees in axapta which were deleted in outlook
            i = 1;
            while (!_syncOnlyOrganizer && i <= conlen(entryIdList))
            {
                while select forupdate smmAttendeeTable where smmAttendeeTable.OrganizerActivityId == smmActivities.ActivityNumber
                && smmAttendeeTable.ReqType == _smmAttendeeReqType && smmAttendeeTable.Type != smmAttendeeType::Organizer
                {
                    if (!confind(entryIdList,smmAttendeeTable.OutlookEntryID))
                    {
                         smmAttendeeTable.delete();
                    }
                }
                i++;
            }

New code:

// Delete attendees in axapta which were deleted in outlook
            i = 1;
            while (!_syncOnlyOrganizer && i <= conlen(entryIdList))
            {
                while select forupdate smmAttendeeTable where smmAttendeeTable.OrganizerActivityId == smmActivities.ActivityNumber
                && smmAttendeeTable.ReqType == _smmAttendeeReqType && smmAttendeeTable.Type != smmAttendeeType::Organizer
                {
                    if (!confind(entryIdList,smmAttendeeTable.OutlookEntryID))
                    {
                        if(SmmAttendeeTable::findOrganizer(smmActivities.ActivityNumber).AttendeeId == smmAttendeeTable.AttendeeId)
                        {
                            smmAttendeeTable.delete(false);
                        }
                        else
                        {
                            smmAttendeeTable.delete();
                        }
                    }
                }
                i++;
            }

 

 

--author: Tariq Bell
--editor: Tariq Bell
--date: 20/Sep/2011