Is there a way to do pessimistic locking for more than 30 seconds

Hi

Is there a way to do pessimistic locking for more than 30 seconds or is there a way where couchbase can wait till the lock is released (in this case more than more than 30 seconds).

Thanks & Regards
Raghu

You posted this under N1QL. Can you tell us exactly what you are trying to do.

The lock settings controlled by these properties of the data service: ep_getl_default_timeout and ep_getl_max_timeout.

To get current values you can run stats:

$ cbc stats | grep getl
localhost:11210	ep_getl_default_timeout	15
localhost:11210	ep_getl_max_timeout	30

You can change them using the following command:

curl -i -XPOST -u Administrator:password http://localhost:8091/diag/eval \
     --data 'ns_bucket:update_bucket_props("default", [{extra_config_string, "getl_max_timeout=142"}]).' 

Where Administrator:password are admin credentials, "default" is the name of the bucket, localhost:8091 endpoint of one of the cluster nodes and 142 is new value for maximum pessimistic lock timeout. Note that to apply settings, you have to manually restart memcached nodes (pkill memcached on each cluster node, the supervisor will start them automatically).

If you will do everything right, you will see the setting being applied:

$ cbc stats | grep getl
localhost:11210	ep_getl_default_timeout	15
localhost:11210	ep_getl_max_timeout	142
1 Like

@avsej,

Thanks for your reply, but do you have any equivalent commands which I can run in cbq command prompt or cbq query window.

Thanks & Regards
Raghu

no. what makes you think that locking related to N1QL? maybe I misunderstood it.

Right now, the cbq / query tools only support “strictly N1QL” commands. We have not yet implemented a general-purpose database shell like other databases have.

Hi avsej

I have tried with CURL statement as you suggested above in this thread. (curl -i -XPOST -u Administrator:password http://localhost:8091/diag/eval \ --data 'ns_bucket:update_bucket_props("default", [{extra_config_string, "getl_max_timeout=120"}]).')

I have successfully changed the ep_getl_max_timeout value to 120, also restarted my couchbase server. Below is the screen shot of the same.

But when I try with below code, lock is working only for 15 seconds not for 100 seconds. Seems like, it is taking the ep_getl_default_timeout value. Could you please help me to over come this issue.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Couchbase.Configuration.Client;
using Couchbase.Core;
using Couchbase.IO;
using System.Threading;

namespace Couchbase.Examples.PessimisticConcurrencyWithLock
{
    class Program
    {
        static void Main(string[] args)
        {
            ClusterHelper.Initialize(new ClientConfiguration
            {
                Servers = new List<Uri>
                {
                    new Uri("http://localhost:8091/")
                }
            });
            var bucket = ClusterHelper.GetBucket("default");
            // Mallik try to get locked one
            var revision0 = new Post
            {
                PostId = "p0001",
                Author = "Stuie27",
                Published = new DateTime(2012, 1, 13),
                Content = "A really cool blog post!",
                Views = 0
            };

            //insert the first revision
            bucket.Upsert(revision0.PostId, revision0);

            Task.Run(() => UpdatePostWithLockAsync(revision0));

            Console.Read();
            ClusterHelper.Close();
        }

        static async Task<bool> UpdatePostWithLockAsync(Post modified)
        {
            var bucket = ClusterHelper.GetBucket("default");
            var success = false;

            //get the original document - if it doesn't exist fail
            var result = await bucket.GetWithLockAsync<Post>(modified.PostId, TimeSpan.FromSeconds(100));

            Thread.Sleep(14000);
            result = await bucket.GetWithLockAsync<Post>(modified.PostId, TimeSpan.FromSeconds(100));
            var x1 = result.Success;


            Thread.Sleep(50000);
            result = await bucket.GetWithLockAsync<Post>(modified.PostId, TimeSpan.FromSeconds(100));
            var x = result.Success;

            Thread.Sleep(50);

            result = await bucket.GetWithLockAsync<Post>(modified.PostId, TimeSpan.FromSeconds(60));

            if (result.Success)
            {
                //update the original documents fields
                var original = result.Value;
                original.Content = modified.Content;
                original.Author = modified.Author;
                original.Views = original.Views++;

                //perform the mutation passing in the CAS value
                  var updated = await bucket.UpsertAsync(original.PostId, original, result.Cas);
                
                if (updated.Success)
                {
                    success = true;
                }
               //await bucket.UnlockAsync(original.PostId, result.Cas);
            }
            return success;
        }

        
    }
}

Thanks in advance,

Mallik

@tmr10061984 -

I am not quite sure you understand what GetWithLockAsync does; it doesn’t lock the document from additional reads, it merely locks it from mutation for the duration of the lock.

-Jeff

Yes, it does not allow to modify it without specifying CAS value, if you know it, you can modify locked value, as knowing CAS value guarantees that integrity will not be violated.

Can’t you update ep_getl_default_timeout in the same as you did for getl_max_timeout ??

I tried setting both the values one by one via the above curl method, but seems extra_config_string can set only one value at a time. Its not also accepting array of items.

Also noted, if we set the value of getl_default_timeout greater than getl_max_timeout (via the above curl method) then, in node.js sdk, while locking if we pass a value greater than getl_max_timeout then it takes the value of getl_default_timeout which is greater than getl_max_timeout.
e.g.
If we set the below values via curl
getl_default_timeout = 60
getl_max_timeout = 30
While locking (getAndLock) if we pass lockTime to say 40 then the lock is held for 60s and not the maximum value of 30.

Can we hard code the settings getl_max_timeout and getl_default_timeout in any config files (instead of using curl to set) like in static_config file? Tried few options, but doesn’t work.
{getl_default_timeout, 60}.
{ep_getl_default_timeout, 60}.