Introduction
In this article, we will discuss how to create a distributed lock with Redis in .NET Core.
When we build distributed systems, we will face multiple processes that handle a shared resource together. It will cause some unexpected problems due to the fact that only one of them can utilize the shared resource at a time!
We can use a distributed lock to solve this problem.
Why Distributed Lock?
As usual, we will use a lock to handle this problem.
The following shows some sample codes demonstrating the use of a lock.
public void SomeMethod()
{
// Do something...
lock (obj)
{
// Do ....
}
// Do something...
}
However, this type of lock cannot help us to work the problem well! This is an in-process lock that can only solve one process with shared resources.
This is also the main reason why we need a distributed lock!
I will use Redis to create a simple distributed lock here.
And why do I use Redis to do this job? Because of Redis's single-threaded nature and its ability to perform atomic operations.
How To Create A Lock?
I will create a .NET Core Console application to show you.
Before the next step, we should run up the Redis server!

StackExchange.Redis is the most popular Reids client on .NET, and there is no doubt that we will use it to do the following jobs.
Creating the connection with Redis at first.
/// <summary>
/// The lazy connection.
/// </summary>
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
ConfigurationOptions configuration = new ConfigurationOptions
{
AbortOnConnectFail = false,
ConnectTimeout = 5000,
};
configuration.EndPoints.Add("localhost", 6379);
return ConnectionMultiplexer.Connect(configuration.ToString());
});
/// <summary>
/// Gets the connection.
/// </summary>
/// <value>The connection.</value>
public static ConnectionMultiplexer Connection => lazyConnection.Value;
In order to request a lock on a shared resource, we do the following.
SET resource_name unique_value NX PX duration
The resource_name is a value that all instances of your application would share.
The unique_value is something that must be unique to each instance of your application. And the purpose of this unique value is to remove the lock (unlock).
Finally, we also provide a duration (in milliseconds), after which the lock will be automatically removed by Redis.
Here is the implementation in C# code.
/// <summary>
/// Acquires the lock.
/// </summary>
/// <returns><c>true</c>, if lock was acquired, <c>false</c> otherwise.</returns>
/// <param name="key">Key.</param>
/// <param name="value">Value.</param>
/// <param name="expiration">Expiration.</param>
static bool AcquireLock(string key, string value, TimeSpan expiration)
{
bool flag = false;
try
{
flag = Connection.GetDatabase().StringSet(key, value, expiration, When.NotExists);
}
catch (Exception ex)
{
Console.WriteLine($"Acquire lock fail...{ex.Message}");
flag = true;
}
return flag;
}
Here is the code to test the acquire lock.



calumPosted Nov 5, 2020, 10:10 AM
Thanks for the article. I was looking into this issue myself. One question if Redis is single thread why do you need a lock in the first place? Shouldn't Redis handle it?
Bohdan StupakPosted Jul 6, 2019, 3:16 PM
Nice one :) Have you considered existing distributed lock implementations like this library? https://github.com/samcook/RedLock.net
yiliang LiuPosted Apr 29, 2019, 6:00 AM
Nice article thank you for sharing...
Hadshana KamalanathanPosted Jul 16, 2018, 5:36 PM
Thank you for sharing