7

I am trying to update the contact facet properties using next code (trimmed example)...

var contactManager = Factory.CreateObject("tracking/contactManager", true) as ContactManager;

Contact contact = null;
var lockResult = contactManager.TryLoadContact(contactId);

switch (lockResult.Status)
{
    case LockAttemptStatus.Success:
        contact = lockResult.Object;
        contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
    default:
        contact = null;
}

if (contact != null)
{
    // update contact properties.

    contactManager.SaveAndReleaseContact(contact);
}

While I am doing this, the contact is in active engagement flow.

After I updated the contact and the method contactManager.SaveAndReleaseContact(contact) was called, I am trying to execute a trigger in the engagement flow for this contact. And it does not work because the contact is still locked. I can see log message:

ERROR Sitecore.Analytics.Automation.AutomationContactManager: Cannot obtain lock on contact: 64dec422-f08d-4932-8369-7313d60b530f. Status: AlreadyLocked

So the question is.. how to make sure the contact is successfully released?

I can also see there are overloads for TryLoadContact method:

contactManager.TryLoadContact(Guid contactId);
contactManager.TryLoadContact(Guid contactId, bool exclusive);
contactManager.TryLoadContact(Guid contactId, int lockDurationMinutes);
contactManager.TryLoadContact(Guid contactId, int lockDurationMinutes, bool exclusive);

Does anyone know what the bool exclusive means and the int lockDurationMinutes? that int lockDurationMinutes - will it release the lock once the specified minutes passed? how and when we can use the bool exclusive option?

Is there a way to release the contact on demand?

1 Answer 1

12

Mechanics of the Contact Manager

You are using the ContactManager class. Underneath, it uses two storage types:

  • ContactRepository which works with the Collection database;
  • SharedSessionStateManager which works with the Shared Session.

When you call .TryLoadContact(contactId), the contact is locked in the Collection DB and loaded into the Shared Session. It is then also locked in the Shared Session so that your current thread can work with the contact exclusively.

Next time you call .TryLoadContact(contactId), the contact will be locked and loaded from the Shared Session without querying the Collection DB (where it is already locked to the current web cluster).

When you call .SaveAndReleaseContact(contact), the contact is released in the Shared Session, so other threads and members of the web cluster can use it. It is not released in the Collection DB though - it remains locked until the Shared Session expires.

The correct way to release a contact

If you want the contact to be unlocked in the Collection DB (via the underlying Contact Repository), the method you should call instead is:

contactManager.SaveAndReleaseContactToXdb(contact.ContactID);

This method will remove the contact from the Shared Session, then save and unlock it in the Collection Database. Note that a call to this method will force the SaveAndReleaseContact to be called first.

The overrides of TryLoadContact

contactManager.TryLoadContact(Guid contactId);
contactManager.TryLoadContact(Guid contactId, bool exclusive);
contactManager.TryLoadContact(Guid contactId, int lockDurationMinutes);

The above three methods all end up calling this method:

contactManager.TryLoadContact(Guid contactId, int lockDurationMinutes, bool exclusive);

exclusive

The exclusive argument defaults to true if unspecified. This argument defines whether to lock the contact in the Shared Session exclusively. If it's set to true, that means you intend to change the contact. This means that other threads will have to wait before they can get the contact from the Shared Session.

Note that, using the above methods, the contact will always be locked in the Collection DB. If you want to read a contact from the Collection DB without obtaining an exclusive lock, you should use another method:

contactManager.LoadContactReadOnly(Guid contactId);

lockDurationMinutes

This argument defaults to (roughly) the length of the current private (ASP.NET) session + 1 minute.

It determines for how many minutes the contact should stay locked in the Collection DB.

1
  • Works like a charm.. as always ;) Dec 9, 2016 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.