13

I've got a site where I'm invoking Tracker.Current.Session.Identify(), passing in the authenticated user's email address.

It works fine locally, but when deployed the identify call often - but not always - throws the following exception:

ContactLockException: The contact {guid} could not be locked in the xDB

Here's where it seems to get weird: the contact ID in the exception:

  • Is not the same as Tracker.Current.Contact.ContactId
  • Changes every request, if the identify is retried

Tracker.Current.Contact.ContactId remains the same throughout. The SC_ANALYTICS_GLOBAL_COOKIE is also static, as is the session ID cookie.

I've checked that the Analytics.ClusterName is correctly set in all cases.

  • Sitecore 8.1 Update-1
  • SQL Session (shared + private)

Has anyone experienced this before and solved it?

Edit: I know what is happening, but I don't yet know why.

Here's the scenario:

  • alice visits the site, logs in, and gets a Known contact associated to the browser cookie
  • bob visits the site, on the same computer as Alice, and logs in using the same browser. Now when we identify the contact as bob, xDB realizes that the current contact needs to be split off because it's already identified as someone else (alice).
  • so xDB creates a new contact ID to put bob into, sets it to have Identifier = bob and Level = Known, and then calls ContactManager.FlushContactToXdb() on it.

Good so far, right? Making sure bob's data doesn't overwrite alice's, even though they have been from the same browser/global analytics cookie.

The error here comes into play later in the identify process when it calls contactManager.TryLoadContact(). This is done to get the existing contact from xDB - in this case, it's using the new contact ID it created for bob.

TryLoadContact(), however, is returning that the contact was not found (LockAttemptStatus = NotFound).

TL;DR it appears that calling ContactManager.FlushContactToXdb(id) immediately followed by contactManager.TryLoadContact(id) is resulting in being unable to load the contact from xDB!

FWIW, Mongo is not a replica set in this case so it couldn't be that a write hadn't propagated to a replica member. Unless Mongo writes are async, which maybe they are...

Edit 2

I've verified that for some reason data is not being written to xDB. The only contacts present are those that were written as a test when I pointed my local dev instance at the shared dev mongo DBs.

I have also verified steps in https://kb.sitecore.net/articles/977445 are okay

  • Checked connectivity from CM server to Mongo using robomongo
  • Private and shared session are using SQL sessions
  • CDN not present
  • Global.asax is present and inherits from Sitecore base class
  • Sc.VisitorIdentification() is on the layout
  • IgnoreUrlPrefixes does not contain layouts
  • Sitecore.MvcAnalytics.config is present
  • Verified that enableTracking is true on the site

So data isn't being written. And worse exceptions don't seem to be getting thrown - there's nothing at all in the logs, and Sitecore seems unaware that FlushContactToXdb() has not worked.

  • Kam, how do you know .TryLoadContact() returns the status of NotFound? It could potentially return AlreadyLocked (unlikely) or DatabaseUnavailable. Have you verified that the contacts with those IDs end up created and unlocked in MongoDB? – Dmytro Shevchenko Jun 28 '17 at 7:37
  • I know because I decompiled the Identify method and ran it :) – Kam Figy Jun 28 '17 at 16:10
  • 1
    @DmytroShevchenko I did find that data wasn't being written and added notes in the question about it. But I'm mystified as to why - have tried all the tricks I know of :| – Kam Figy Jun 28 '17 at 16:17
  • Try disabling robot detection by setting both Analytics.Robots.IgnoreRobots and Analytics.AutoDetectBots to false in the Sitecore.Analytics.Tracking.config. If contacts are saved after this, then we'll know which part of the code is at the root of the issue. – Dmytro Shevchenko Jun 28 '17 at 20:28
  • @DmytroShevchenko thank you for your help - I figured it out below. – Kam Figy Jun 29 '17 at 14:19
5

I have solved this issue. It was due to following the recommended enable/disable configuration guide (https://doc.sitecore.net/sitecore_experience_platform/setting_up__maintaining/xdb/configuring_servers/configure_a_content_management_server), which tells me to disable the following config files for a CM instance (this was occurring on a test environment that had only one CM):

  • Sitecore.Analytics.Tracking.Aggregation.config
  • Sitecore.Analytics.Tracking.Database.config
  • Sitecore.Analytics.Tracking.RobotDetection.config

Specifically disabling Sitecore.Analytics.Tracking.Database.config caused no data to be written to MongoDB - which might be ok in a production CM, except that in this case it breaks Identify() because of its need to read a contact back out of xDB after creating it.

No database, nothing to read back from = contact not found, so cannot get a lock on what doesn't exist.

Moral of the story: Don't disable these files on a CM if you're identifying contacts, or if there are no CDs in the environment. I've filed a bug with support (487945).

1

Have you checked if you have sporadic availability problems with your Mongo?

Try setting this to true in your sitecore.analytics.tracking.config:

<setting name="Analytics.UseSubmitQueue" value="true" />

If with that setting the problem goes away, then Sitecore has intermittent problems with Mongo not being available. That setting makes Sitecore use a failover local queue for contact activities.

Alternatively, the sitecore community site describes a similar issue:

https://community.sitecore.net/developers/f/8/t/1771

  • Does not seem to be true in this case - can connect using robomongo to the (on-prem) Mongo server from the CM instance. – Kam Figy Jun 28 '17 at 16:16
0

Two things:

  1. Your configurations according to the Sitecore xDB documentation, should be up to date. For example, in your ConnectionStrings.config, reporting and tracking.history should be removed. And the following config files should be disabled:

Sitecore.Analytics.Automation.TimeoutProcessing.config

Sitecore.Analytics.Processing.Aggregation.Services.config

Sitecore.Analytics.Processing.Services.config

Sitecore.Analytics.Reporting.config

  1. Your default Sitecore License should have xDB enabled. You should be seeing an entry for xDB in your Sitecore License. If you do not see this entry, then it means you need a new license.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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