From 6bd0c4bc0cd61e97f2dcdccb836067532a354efc Mon Sep 17 00:00:00 2001 From: malik masis Date: Wed, 9 Mar 2022 13:30:16 +0300 Subject: [PATCH 1/7] Documented the distributed lock for the Redis Provider --- docs/en/Distributed-Lock.md | 72 +++++++++++++++++++++++++++++++++++++ docs/en/docs-nav.json | 4 +++ 2 files changed, 76 insertions(+) create mode 100644 docs/en/Distributed-Lock.md diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Lock.md new file mode 100644 index 0000000000..ff337b75eb --- /dev/null +++ b/docs/en/Distributed-Lock.md @@ -0,0 +1,72 @@ +# Distributed Lock +Distributed locks are very useful to manage many processes that request the same object. +They are used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. + +# Providers +`MedallionAbpDistributedLock` +Distributed locks system provides an abstraction that can be implemented by any vendor/provider. +ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. + +This provider contains a method named TryAcquireAsync and this method returns null if the lock could not be handled. +> Name is a mandatory field. It keeps the locked provider name. +> Timeout is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. +>CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects + + +Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. + +````csharp +using Medallion.Threading; +using Medallion.Threading.Redis; +namespace AbpDemo +{ + public class MyModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + //the other configurations + var configuration = context.Services.GetConfiguration(); + + context.Services.AddSingleton(sp => + { + var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); + return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); + }); + } + } +} +```` + +Also, you should add your Redis configuration in appsetting.json +````json +"Redis": { + "Configuration": "127.0.0.1" +} +```` + +> To use in APB, you should download the below NuGet package. +It already contains DistributedLocking.Abstractions and no need to download as well. +````powershell +Install-Package Volo.Abp.DistributedLocking -Version 5.1.4 +```` + +````csharp +using Volo.Abp.DistributedLocking; +namespace AbpDemo +{ + public class MyService : ITransientDependency + { + private readonly IAbpDistributedLock _distributedLock; + public MyService(IAbpDistributedLock distributedLock) + { + _distributedLock = distributedLock; + } + + await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) + { + if (handle != null) + { + //your code + } + } +```` \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 6df98cb05a..f039d02f1b 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -300,6 +300,10 @@ "text": "Data Seeding", "path": "Data-Seeding.md" }, + { + "text": "Distributed Lock", + "path": "Distributed-Lock.md" + }, { "text": "Email Sending", "items": [ From ac01c5b3a181eda19dd029215e4dca42ba6e7c6a Mon Sep 17 00:00:00 2001 From: malik masis Date: Wed, 9 Mar 2022 16:36:51 +0300 Subject: [PATCH 2/7] Applied the advice of the reviewer More summarize NuGet package definiation type Forgotten method --- docs/en/Distributed-Lock.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Lock.md index ff337b75eb..8593560b3d 100644 --- a/docs/en/Distributed-Lock.md +++ b/docs/en/Distributed-Lock.md @@ -1,16 +1,20 @@ # Distributed Lock Distributed locks are very useful to manage many processes that request the same object. -They are used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. +In a normal case, accessing the same object from different threads or services can corrupt the value of objects. +In terms of accuracy, we may need to protect the value that's why a lock will be necessary. +On another hand, it will protect from more times triggered hence you will provide more efficiency. +To summarize, It's used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. # Providers -`MedallionAbpDistributedLock` Distributed locks system provides an abstraction that can be implemented by any vendor/provider. + + * `MedallionAbpDistributedLock` ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. This provider contains a method named TryAcquireAsync and this method returns null if the lock could not be handled. > Name is a mandatory field. It keeps the locked provider name. > Timeout is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. ->CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +> CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. @@ -44,10 +48,10 @@ Also, you should add your Redis configuration in appsetting.json } ```` -> To use in APB, you should download the below NuGet package. +> To use in ABP, you should download the below NuGet package. It already contains DistributedLocking.Abstractions and no need to download as well. ````powershell -Install-Package Volo.Abp.DistributedLocking -Version 5.1.4 +abp add-package Volo.Abp.DistributedLocking ```` ````csharp @@ -61,12 +65,17 @@ namespace AbpDemo { _distributedLock = distributedLock; } - - await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) + + public async Task MyMethodAsync() { - if (handle != null) + await using (var handle = await _distributedLock.TryAcquireAsync("NameOfLock")) { - //your code - } + if (handle != null) + { + //your code + } + } } + } +} ```` \ No newline at end of file From 50b66102c8ac0f4b03bec4e52b60d0f17f089e92 Mon Sep 17 00:00:00 2001 From: malik masis Date: Thu, 10 Mar 2022 09:12:42 +0300 Subject: [PATCH 3/7] Added quotes According to the reviewer, added quotes for method and parameters name --- docs/en/Distributed-Lock.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Lock.md index 8593560b3d..ae1d5b9232 100644 --- a/docs/en/Distributed-Lock.md +++ b/docs/en/Distributed-Lock.md @@ -11,10 +11,10 @@ Distributed locks system provides an abstraction that can be implemented by any * `MedallionAbpDistributedLock` ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. -This provider contains a method named TryAcquireAsync and this method returns null if the lock could not be handled. -> Name is a mandatory field. It keeps the locked provider name. -> Timeout is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. -> CancellationToken is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. +> `Name` is a mandatory field. It keeps the locked provider name. +> `Timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. +> `CancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. From f3aa932b3e00ad73804453b30d88b22f3a993116 Mon Sep 17 00:00:00 2001 From: malik masis Date: Thu, 10 Mar 2022 14:17:12 +0300 Subject: [PATCH 4/7] Made changes on the document It will be continued enhancement --- ...ributed-Lock.md => Distributed-Locking.md} | 85 +++++++++---------- docs/en/docs-nav.json | 2 +- 2 files changed, 41 insertions(+), 46 deletions(-) rename docs/en/{Distributed-Lock.md => Distributed-Locking.md} (58%) diff --git a/docs/en/Distributed-Lock.md b/docs/en/Distributed-Locking.md similarity index 58% rename from docs/en/Distributed-Lock.md rename to docs/en/Distributed-Locking.md index ae1d5b9232..d79dff8674 100644 --- a/docs/en/Distributed-Lock.md +++ b/docs/en/Distributed-Locking.md @@ -1,23 +1,47 @@ -# Distributed Lock -Distributed locks are very useful to manage many processes that request the same object. -In a normal case, accessing the same object from different threads or services can corrupt the value of objects. +# Distributed Locking +Distributed locking is very useful to manage many processes that request the same object. +In a normal case, accessing the same object from different applications can corrupt the value of resources. In terms of accuracy, we may need to protect the value that's why a lock will be necessary. -On another hand, it will protect from more times triggered hence you will provide more efficiency. -To summarize, It's used to handle conflict between these requests. Once obtaining anyone it, the others need to wait till give up free. -# Providers -Distributed locks system provides an abstraction that can be implemented by any vendor/provider. +> To use in ABP, you should download the below NuGet package or can open any command apps and run the below command. +````powershell +abp add-package Volo.Abp.DistributedLocking +```` - * `MedallionAbpDistributedLock` -ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. Here, I will show the Redis provider. +````csharp +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("NameOfLock")) + { + if (handle != null) + { + //your code + } + } + } + } +} +```` This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. -> `Name` is a mandatory field. It keeps the locked provider name. -> `Timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. -> `CancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise it will be seen as a different lock. +`timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. +`cancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. ABP implements the Redis provider for you and you may customize the others yourselves. -Also, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. +Firstly, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. ````csharp using Medallion.Threading; @@ -41,41 +65,12 @@ namespace AbpDemo } ```` -Also, you should add your Redis configuration in appsetting.json +Also, you should add your Redis configuration in appsetting.json. +You may change the structure of the JSON file but it must match with the above configuration code. ````json "Redis": { "Configuration": "127.0.0.1" } ```` -> To use in ABP, you should download the below NuGet package. -It already contains DistributedLocking.Abstractions and no need to download as well. -````powershell -abp add-package Volo.Abp.DistributedLocking -```` - -````csharp -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("NameOfLock")) - { - if (handle != null) - { - //your code - } - } - } - } -} -```` \ No newline at end of file +As mentioned the above, this implemantition is for Redis and for more detail you can visit [the official site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index f039d02f1b..16edb1a7cc 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -302,7 +302,7 @@ }, { "text": "Distributed Lock", - "path": "Distributed-Lock.md" + "path": "Distributed-Locking.md" }, { "text": "Email Sending", From 533a59536f74084beeb31bf88b5d9ee362836bf8 Mon Sep 17 00:00:00 2001 From: malik masis Date: Fri, 11 Mar 2022 17:06:41 +0300 Subject: [PATCH 5/7] Reworked on summarize Completed working on changes according to the feedback of the reviewer. --- docs/en/Distributed-Locking.md | 11 ++++++----- docs/en/docs-nav.json | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index d79dff8674..7a87132fa6 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -1,7 +1,8 @@ # Distributed Locking -Distributed locking is very useful to manage many processes that request the same object. -In a normal case, accessing the same object from different applications can corrupt the value of resources. -In terms of accuracy, we may need to protect the value that's why a lock will be necessary. +Distributed locking is very useful to manage many applications that trying 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 resources. +On this occasion, distributed locking protects the correct value throughout the applications. > To use in ABP, you should download the below NuGet package or can open any command apps and run the below command. ````powershell @@ -35,7 +36,7 @@ namespace AbpDemo ```` This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. -`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise it will be seen as a different lock. +`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise, it will be seen as a different lock. `timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. `cancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects @@ -73,4 +74,4 @@ You may change the structure of the JSON file but it must match with the above c } ```` -As mentioned the above, this implemantition is for Redis and for more detail you can visit [the official site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file +As mentioned above, this implementation is for Redis and for more detail you can visit [the GitHub site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 16edb1a7cc..1fdc6f510a 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -301,7 +301,7 @@ "path": "Data-Seeding.md" }, { - "text": "Distributed Lock", + "text": "Distributed Locking", "path": "Distributed-Locking.md" }, { From 0a6d01454c714d3eb3b89488484fe7aa0b663033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 11 Mar 2022 22:11:16 +0300 Subject: [PATCH 6/7] Revised the distributed locking document. --- docs/en/Distributed-Locking.md | 107 +++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index 7a87132fa6..cbcff02a48 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -1,77 +1,104 @@ # Distributed Locking -Distributed locking is very useful to manage many applications that trying to access the same resource. +Distributed locking is technique to manage many applications that trying 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 resources. -On this occasion, distributed locking protects the correct value throughout the applications. -> To use in ABP, you should download the below NuGet package or can open any command apps and run the below command. +> ABP's current distributed locking implementation is based on the [DistributedLock](https://github.com/madelson/DistributedLock) library. + +## Installation + +You can open a command-line terminal and type the following command to install the [Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking) package it into your project: + ````powershell abp add-package Volo.Abp.DistributedLocking ```` -````csharp -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("NameOfLock")) - { - if (handle != null) - { - //your code - } - } - } - } -} -```` +This package provides the necessary API to use the distributed locking system, however, you should configure a provider before using it. -This provider contains a method named `TryAcquireAsync` and this method returns null if the lock could not be handled. -`name` is mandatory. It keeps the locked provider name. This name should be unique, otherwise, it will be seen as a different lock. -`timeout` is set as default. If it fells deadlock and doesn't work properly you can use define the time to kill it. -`cancellationToken` is set as default. It enables cooperative cancellation between threads, thread pool work items, or Task objects +### Configuring a provider -ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations) including Redis, SqlServer and ZooKeeper. You may use the one you want. ABP implements the Redis provider for you and you may customize the others yourselves. +The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md). -Firstly, you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class. +For example, if you want to use the [Redis provider](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md), you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the `ConfigureServices` method of your ABP [module](Module-Development-Basics.md) class: ````csharp using Medallion.Threading; using Medallion.Threading.Redis; + namespace AbpDemo { public class MyModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - //the other configurations var configuration = context.Services.GetConfiguration(); context.Services.AddSingleton(sp => { - var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); - return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); + var connection = ConnectionMultiplexer + .Connect(configuration["Redis:Configuration"]); + return new + RedisDistributedSynchronizationProvider(connection.GetDatabase()); }); } } } ```` -Also, you should add your Redis configuration in appsetting.json. -You may change the structure of the JSON file but it must match with the above configuration code. +This code gets the Redis connection string from the [configuration](Configuration.md), so you can add the following lines to your `appsettings.json` file: + ````json "Redis": { "Configuration": "127.0.0.1" } ```` -As mentioned above, this implementation is for Redis and for more detail you can visit [the GitHub site](https://github.com/madelson/DistributedLock#implementations). \ No newline at end of file +## Usage + +There are two ways to use the distributed locking API: ABP's `IAbpDistributedLock` abstraction and [DistributedLock](https://github.com/madelson/DistributedLock) library's API. + +### Using the IAbpDistributedLock service + +`IAbpDistributedLock` is a simple service provided by the ABP framework for simple usage of distributed locking. + +**Example: Using `IAbpDistributedLock.TryAcquireAsync` method** + +````csharp +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. + +### Using DistributedLock library's API + +ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. \ No newline at end of file From ea2b90a26e80fe00515e6e5eb3beb96cd990c231 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Sat, 12 Mar 2022 08:52:04 +0300 Subject: [PATCH 7/7] Update Distributed-Locking.md --- docs/en/Distributed-Locking.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/Distributed-Locking.md b/docs/en/Distributed-Locking.md index cbcff02a48..fd59a6a7c9 100644 --- a/docs/en/Distributed-Locking.md +++ b/docs/en/Distributed-Locking.md @@ -9,7 +9,7 @@ Otherwise accessing the same object from various applications may corrupt the va You can open a command-line terminal and type the following command to install the [Volo.Abp.DistributedLocking](https://www.nuget.org/packages/Volo.Abp.DistributedLocking) package it into your project: -````powershell +````bash abp add-package Volo.Abp.DistributedLocking ```` @@ -17,7 +17,7 @@ This package provides the necessary API to use the distributed locking system, h ### Configuring a provider -The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md). +The [DistributedLock](https://github.com/madelson/DistributedLock) library provides [various of implementations](https://github.com/madelson/DistributedLock#implementations) for the locking, like [Redis](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md) and [ZooKeeper](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.ZooKeeper.md). For example, if you want to use the [Redis provider](https://github.com/madelson/DistributedLock/blob/master/docs/DistributedLock.Redis.md), you should add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the `ConfigureServices` method of your ABP [module](Module-Development-Basics.md) class: @@ -101,4 +101,4 @@ namespace AbpDemo ### Using DistributedLock library's API -ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details. \ No newline at end of file +ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details.