Distributed Locking

Distributed locking is a technique to manage many applications that try to access the same resource. The main purpose is to allow only one of many applications to access the same resource at the same time. Otherwise, accessing the same object from various applications may corrupt the value of the resources.

ABP's current distributed locking implementation is based on the DistributedLock library.

Installation

You can open a command-line terminal and type the following command to install the Volo.Abp.DistributedLocking package into your project:

abp add-package Volo.Abp.DistributedLocking

This package provides the necessary API to use the distributed locking system, however, you should configure a provider before using it.

Configuring a Provider

The DistributedLock library provides various of implementations for the locking, like Redis and ZooKeeper.

For example, if you want to use the Redis provider, you should add DistributedLock.Redis NuGet package to your project, then add the following code into the ConfigureServices method of your ABP module class:

using Medallion.Threading;
using Medallion.Threading.Redis;

namespace AbpDemo
{
    [DependsOn(
            typeof(AbpDistributedLockingModule)
            //If you have the other dependencies, you should do here
    )]
    public class MyModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
        
            context.Services.AddSingleton<IDistributedLockProvider>(sp =>
            {
                var connection = ConnectionMultiplexer
                    .Connect(configuration["Redis:Configuration"]);
                return new 
                    RedisDistributedSynchronizationProvider(connection.GetDatabase());
            });
        }
    }
}

This code gets the Redis connection string from the configuration, so you can add the following lines to your appsettings.json file:

"Redis": {
    "Configuration": "127.0.0.1"
}

Usage

There are two ways to use the distributed locking API: ABP's IAbpDistributedLock abstraction and DistributedLock library's API.

Using the IAbpDistributedLock Service

IAbpDistributedLock is a simple service provided by the ABP for simple usage of distributed locking.

Example: Using the IAbpDistributedLock.TryAcquireAsync method

using Volo.Abp.DistributedLocking; 

namespace AbpDemo
{
    public class MyService : ITransientDependency
    {
        private readonly IAbpDistributedLock _distributedLock;
		public MyService(IAbpDistributedLock distributedLock)
        {
            _distributedLock = distributedLock;
        }
        
        public async Task MyMethodAsync()
        {
            await using (var handle = 
                         await _distributedLock.TryAcquireAsync("MyLockName"))
            {
                if (handle != null)
                {
                    // your code that access the shared resource
                }
            }   
        }
    }
}

TryAcquireAsync may not acquire the lock. It returns null if the lock could not be acquired. In this case, you shouldn't access the resource. If the handle is not null, it means that you've obtained the lock and can safely access the resource.

TryAcquireAsync method gets the following parameters:

  • name (string, required): Unique name of your lock. Different named locks are used to access different resources.
  • timeout (TimeSpan): A timeout value to wait to obtain the lock. Default value is TimeSpan.Zero, which means it doesn't wait if the lock is already owned by another application.
  • cancellationToken: A cancellation token that can be triggered later to cancel the operation.

Configuration

AbpDistributedLockOptions

AbpDistributedLockOptions is the main options class to configure the distributed locking.

Example: Set the distributed lock key prefix for the application

Configure<AbpDistributedLockOptions>(options =>
{
    options.KeyPrefix = "MyApp1";
});

Write that code inside the ConfigureServices method of your module class.

Available Options
  • KeyPrefix (string, default: null): Specify the lock name prefix.

Using DistributedLock Library's API

ABP's IAbpDistributedLock service is very limited and mainly designed to be internally used by the ABP. For your own applications, you can use the DistributedLock library's own API. See its own documentation for details.

The Volo.Abp.DistributedLocking.Abstractions Package

If you are building a reusable library or an application module, then you may not want to bring an additional dependency to your module for simple applications that run as a single instance. In this case, your library can depend on the Volo.Abp.DistributedLocking.Abstractions package which defines the IAbpDistributedLock service and implements it as in-process (not distributed actually). In this way, your library can run properly (without a distributed lock provider dependency) in an application that runs as a single instance. If the application is deployed to a clustered environment, then the application developer should install a real distributed provider as explained in the Installation section.

Contributors


Last updated: July 31, 2024 Edit this page on GitHub

Was this page helpful?

Please make a selection.

To help us improve, please share your reason for the negative feedback in the field below.

Please enter a note.

Thank you for your valuable feedback!

Please note that although we cannot respond to feedback, our team will use your comments to improve the experience.

In this document
Community Talks

Building Modular Monolith Applications Using .NET and ABP Framework

17 Oct, 17:00
Online
Watch the Event
Mastering ABP Framework Book
Mastering ABP Framework

This book will help you gain a complete understanding of the framework and modern web application development techniques.

Learn More