0

I am trying out distributed locks from DistributedLock nuget.

Here's code snippet I use:

class Program
{
    private static SqlConnection _sqlConn = new SqlConnection("my connection string");
   
    static void Main(string[] args)
    {
        int pid;
        using (var p = Process.GetCurrentProcess()) { pid = p.Id; }
        TestSqlLocking(pid).Wait();
    }

    private static async Task TestSqlLocking(int processId)
    {
        _sqlConn.Open();
        var t1 = DoWorkAsyncWithSqlLock($"Process {processId} Client 1");
        var t2 = DoWorkAsyncWithSqlLock($"Process {processId} Client 2");
        var t3 = DoWorkAsyncWithSqlLock($"Process {processId} Client 3");
        var t4 = DoWorkAsyncWithSqlLock($"Process {processId} Client 4");
        await Task.WhenAll(t1, t2, t3, t4);
    }

    private static async Task DoWorkAsyncWithSqlLock(string client)
    {
        var sqlDistributedLock = new SqlDistributedLock("myLock", _sqlConn);
        Console.WriteLine($"SQL Before taking the lock for client [{client}]");
        await using (await sqlDistributedLock.AcquireAsync(TimeSpan.FromSeconds(10)))
        {
            Console.WriteLine($"SQL After taking the lock and doing some work for client [{client}]");
            await Task.Delay(1000);
            Console.WriteLine($"SQL After doing some work and releasing lock for client [{client}]");
        }
    }
}

The thing is I always get timeout after first lock acquiring, as if it never gets released. While it is said that lock will be released after disposing. But that is not hapening. Second task is never able to enter the lock.

Output I get is:

SQL Before taking the lock for client [Process 8864 Client 1]
SQL Before taking the lock for client [Process 8864 Client 2]
SQL Before taking the lock for client [Process 8864 Client 3]
SQL Before taking the lock for client [Process 8864 Client 4]
SQL After taking the lock and doing some work for client [Process 8864 Client 1]
SQL After doing some work and releasing lock for client [Process 8864 Client 1]

Then I get timeout.

Michał Turczyn
  • 32,028
  • 14
  • 47
  • 69
  • @mjwills Obviously, that's just presentatiion of what I am trying to achieve with sample code. Then it will be taken into "real" software I am working on. – Michał Turczyn Aug 18 '21 at 08:27
  • Does the same thing happen if you call `Acquire` synchronously? – mjwills Aug 18 '21 at 08:41
  • Does the same thing happen if you pass in a SQL connection string rather than `_sqlConn`? – mjwills Aug 18 '21 at 08:47
  • @mjwills No, it's not, and working properly... Need to go through source code. – Michał Turczyn Aug 18 '21 at 09:13
  • You are not disposing `_sqlConn`, it should be in a `using` block, although that is unlikely to fix your issue – Charlieface Aug 18 '21 at 10:53
  • `When a connection is passed, the lock will be scoped to that connection` I suspect part of the issue is that by sharing the same connection across multiple `SqlDistributedLock` you "confuse" it. Hence why the docs recommend not to do that. https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.SqlServer.md#implementation-notes – mjwills Aug 18 '21 at 13:11

0 Answers0