How to Lock CouchBase .NET objects properly?

Posted On
So far, the .NET API for CouchBase doesn't have a support for locking the keys from concurrent access. Although it is pretty cool NOSQL DB solution, not having a proper lock feature is a killer for most of (at least mine) use cases. For this and another (I don't remember :p) reasons, I decided to implement a 'temporary' locking solution for CouchBase. Below you will find lockIt and leaveIt methods in order to lock and leave a key from the server.

P.S: It may not be best using below approach on high load systems!!

        
        public static void test()
        {
            CBLock.Lock("MyDBKey", "test");//lock the key for any concurrent access
            try
            {
                //do whatever you want with the value
                string value = CBLock.client.Get("MyDBKey");
                value += "testDone!";
                CBLock.client.Store(StoreMode.Set, "MyDBKEY", value);
            }catch{}
            finally
            {
                //unlock the key for an access to others
                CBLock.Leave("MyDBKey", "test");
            }
        }

        /**
         * CBLock v0.1 Oguz Bastemur 2013
         * Feel free to use this code on any kind of application under any type of license
         */
        public class CBLock
        {

            internal static Couchbase.CouchbaseClient client; // This is your couchbase client

            internal static bool ApplicationRecycling = false; // in case you stop/close etc. your app set it to true

            internal static TimeSpan maxLockTime = new TimeSpan(0, 0, 0, 10); //max lock time is 10 seconds

            public static void Lock(string key, string owner)
            {
                CasResult casResult;

                bool done = false;
                CasResult cr;

                do
                {
                    cr = client.GetWithCas("lo$_" + key);

                    if (String.IsNullOrEmpty(cr.Result))
                    {
                        casResult = client.Cas(StoreMode.Set, "lo$_" + key, owner, maxLockTime, cr.Cas);
                        done = casResult.Result;
                    }
                    else
                        Thread.Sleep(1);
                }
                while (done == false || !ApplicationRecycling);
            }


            public static void Leave(string key, string owner)
            {
                CasResult casResult;

                bool done = false;

                do
                {
                    CasResult cr = client.GetWithCas("lo$_" + key);

                    if (cr.Result == owner)
                    {
                        casResult = client.Cas(StoreMode.Set, "lo$_" + key, "", cr.Cas);

                        done = casResult.Result;
                    }
                    else
                        Thread.Sleep(1);
                }
                while (done == false || !ApplicationRecycling);
            }
        }