How-To: Use a lock

Learn how to use distributed locks to provide exclusive access to a resource

Now that you’ve learned what the Dapr distributed lock API building block provides, learn how it can work in your service. In this guide, an example application acquires a lock using the Redis lock component to demonstrate how to lock resources. For a list of supported lock stores, see this reference page.

In the diagram below, two instances of the same application acquire a lock, where one instance is successful and the other is denied.

The diagram below shows two instances of the same application acquiring a lock, where one instance is successful and the other is denied

The diagram below shows two instances of the same application, where one instance releases the lock and the other instance is then able to acquire the lock.

Diagram showing releasing a lock from multiple instances of same application

The diagram below shows two instances of different applications, acquiring different locks on the same resource.

The diagram below shows two instances of different applications, acquiring different locks on the same resource

Configure a lock component

Save the following component file to the default components folder on your machine.

  1. apiVersion: dapr.io/v1alpha1
  2. kind: Component
  3. metadata:
  4. name: lockstore
  5. spec:
  6. type: lock.redis
  7. metadata:
  8. - name: redisHost
  9. value: localhost:6379
  10. - name: redisPassword
  11. value: <PASSWORD>

Acquire lock

  1. curl -X POST http://localhost:3500/v1.0-alpha1/lock/lockstore
  2. -H 'Content-Type: application/json'
  3. -d '{"resourceId":"my_file_name", "lockOwner":"random_id_abc123", "expiryInSeconds": 60}'
  1. using System;
  2. using Dapr.Client;
  3. namespace LockService
  4. {
  5. class Program
  6. {
  7. [Obsolete("Distributed Lock API is in Alpha, this can be removed once it is stable.")]
  8. static async Task Main(string[] args)
  9. {
  10. string DAPR_LOCK_NAME = "lockstore";
  11. string fileName = "my_file_name";
  12. var client = new DaprClientBuilder().Build();
  13. await using (var fileLock = await client.Lock(DAPR_LOCK_NAME, fileName, "random_id_abc123", 60))
  14. {
  15. if (fileLock.Success)
  16. {
  17. Console.WriteLine("Success");
  18. }
  19. else
  20. {
  21. Console.WriteLine($"Failed to lock {fileName}.");
  22. }
  23. }
  24. }
  25. }
  26. }
  1. package main
  2. import (
  3. "fmt"
  4. dapr "github.com/dapr/go-sdk/client"
  5. )
  6. func main() {
  7. client, err := dapr.NewClient()
  8. if err != nil {
  9. panic(err)
  10. }
  11. defer client.Close()
  12. resp, err := client.TryLockAlpha1(ctx, "lockstore", &dapr.LockRequest{
  13. LockOwner: "random_id_abc123",
  14. ResourceID: "my_file_name",
  15. ExpiryInSeconds: 60,
  16. })
  17. fmt.Println(resp.Success)
  18. }

Unlock existing lock

  1. curl -X POST http://localhost:3500/v1.0-alpha1/unlock/lockstore
  2. -H 'Content-Type: application/json'
  3. -d '{"resourceId":"my_file_name", "lockOwner":"random_id_abc123"}'
  1. using System;
  2. using Dapr.Client;
  3. namespace LockService
  4. {
  5. class Program
  6. {
  7. static async Task Main(string[] args)
  8. {
  9. string DAPR_LOCK_NAME = "lockstore";
  10. var client = new DaprClientBuilder().Build();
  11. var response = await client.Unlock(DAPR_LOCK_NAME, "my_file_name", "random_id_abc123"));
  12. Console.WriteLine(response.status);
  13. }
  14. }
  15. }
  1. package main
  2. import (
  3. "fmt"
  4. dapr "github.com/dapr/go-sdk/client"
  5. )
  6. func main() {
  7. client, err := dapr.NewClient()
  8. if err != nil {
  9. panic(err)
  10. }
  11. defer client.Close()
  12. resp, err := client.UnlockAlpha1(ctx, "lockstore", &UnlockRequest{
  13. LockOwner: "random_id_abc123",
  14. ResourceID: "my_file_name",
  15. })
  16. fmt.Println(resp.Status)
  17. }

Next steps

Read the distributed lock API overview to learn more.

Last modified December 15, 2022: update unlock dotnet code (8fdb4ca7)