Thread synchronization within a tenant

Topics: Writing modules
Jun 17, 2013 at 4:29 AM
I have a custom module that is used by multiple websites (tenants). Part of the code in this module needs to check and decrement a counter on a content item. In this scenario, these updates could easily occur from multiple users at the same time so I wish to place a lock around the section of code that checks the counter value and modifies it.

I want to avoid locking on a static object within the class as I believe this will have the effect of blocking users across all tenants in the system, when I only need to block users within the same tenant.

One approach I've seen used (for example in the taxonomies module) is to make my service class based on an ISingletonDependency rather than an IDependency, thus only one instance of the service class is created for each tenant, and I can then define a non-static syncLock object within this class to lock on.

However when doing this, I started to get distributed transaction errors out of nHibernate, since my service class (the logic within the lock) is updating content items, but I suspect now the session it is using is different to the session for the current request.

So the approach I've taken is to leave my service class as an IDependency, and then define a very simple ISingletonDependency based (ISyncLockProvider) class that exposes an object to lock on. I then consume this from within my service and lock on the object it returns.

So I really just want to know if this is an ok approach to take to ensure tenant scoped thread synchronization with service logic?
Jun 26, 2013 at 6:29 AM
Sounds OK-ish, but singletons and locks never seem completely ok to me. There is so much potential for deadlocks that I always try to find an alternate approach that doesn't require them. Can think of one in this case however.