---
slug: /references/locking-service
tags:
  - locking
  - server
  - how to
sidebar_label: Use Locking Module
---

import { TypeList } from "docs-ui"

# How to Use Locking Module

In this document, you’ll learn about the different methods in the Locking Module's service and how to use them.

---

## Resolve Locking Module's Service

In your workflow's step, you can resolve the Locking Module's service from the Medusa container:

```ts
import { Modules } from "@medusajs/framework/utils"
import { createStep } from "@medusajs/framework/workflows-sdk"

const step1 = createStep(
  "step-1",
  async ({}, { container }) => {
    const lockingModuleService = container.resolve(
      Modules.LOCKING
    )
    
    // TODO use lockingModuleService
  } 
)
```

You can then use the Locking Module's service's methods in the step. The rest of this guide details these methods.

---

## execute

This method executes a giuven asynchronous job with a lock on the given keys. You can optionally pass a 
provider name to be used for locking. If no provider is passed, the default provider (in-memory or the 
provider configuerd in `medusa-config.ts`) will be used.

### Example

For example, to use the lock module when deleting a product:

```ts
await lockingModuleService.execute("prod_123", async () => {
   // assuming you've resolved the product service from the container
   await productModuleService.delete("prod_123")
})
```

In the above example, the product of ID `prod_123` is locked while it's being deleted.

To specify the provider to use for locking, you can pass the provider name in the `args` argument:

```ts
await lockingModuleService.execute("prod_123", async () => {
  // assuming you've resolved the product service from the container
  await productModuleService.delete("prod_123")
}, {
  provider: "lp_my-lock"
})
```

### Type Parameters

<TypeList types={[{"name":"T","type":"`object`","description":"The type of the job's result.","optional":true,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="execute"/>

### Parameters

<TypeList types={[{"name":"keys","type":"`string` \\| `string`[]","description":"The keys to lock durng the job's execution.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"job","type":"() => Promise&#60;T&#62;","description":"The asynchronous job to execute while the keys are locked.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"args","type":"`object`","description":"Additional arguments for the job execution.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"timeout","type":"`number`","description":"The timeout (in seconds) for acquiring the lock. If the time out is passed, the job is canceled and the lock is released.\nIts value defaults to `5` seconds if no value is passed or if you pass a value less than `1`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider","type":"`string`","description":"The provider name to use for locking. If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"sharedContext","type":"[Context](../../../types/interfaces/types.Context/page.mdx)","description":"A context used to share resources, such as transaction manager, between the application and the module.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"transactionManager","type":"TManager","description":"An instance of a transaction manager of type `TManager`, which is a typed parameter passed to the context to specify the type of the `transactionManager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"manager","type":"TManager","description":"An instance of a manager, typically an entity manager, of type `TManager`, which is a typed parameter passed to the context to specify the type of the `manager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"isolationLevel","type":"`string`","description":"A string indicating the isolation level of the context. Possible values are `READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`, or `SERIALIZABLE`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"enableNestedTransactions","type":"`boolean`","description":"A boolean value indicating whether nested transactions are enabled.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"eventGroupId","type":"`string`","description":"A string indicating the ID of the group to aggregate the events to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"transactionId","type":"`string`","description":"A string indicating the ID of the current transaction.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"messageAggregator","type":"[IMessageAggregator](../../../types/interfaces/types.IMessageAggregator/page.mdx)","description":"An instance of a message aggregator, which is used to aggregate messages to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"requestId","type":"`string`","description":"A string indicating the ID of the current request.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"idempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the current workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"parentStepIdempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the parent workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="execute"/>

### Returns

<TypeList types={[{"name":"Promise","type":"Promise&#60;T&#62;","optional":false,"defaultValue":"","description":"The result of the job execution.","expandable":false,"children":[{"name":"T","type":"T","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="execute"/>

___

## acquire

This method acquires a lock on the given keys. You can optionally pass a provider name to be used for locking. 
If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.

You can pass an owner for the lock, which limits who can extend or release the acquired lock. Then, if you use this method again
passing the same owner, the lock's expiration time is extended with the value passed in the `expire` argument. Otherwise, if you pass a
different owner, the method throws an error.

### Example

For example, to acquire a lock on a product with ID `prod_123` for a user with ID `user_123`:

```ts
await lockingModuleService.acquire("prod_123", {
  ownerId: "user_123",
  expire: 60
})
```

In this example, you acquire a lock on the product with ID `prod_123` for the user with ID `user_123`. You extend the 
lock's expiration time by `60` seconds.

To specify the provider to use for locking, you can pass the provider name in the `args` argument:

```ts
await lockingModuleService.acquire("prod_123", {
  ownerId: "user_123",
  expire: 60,
  provider: "lp_my-lock"
})
```

### Parameters

<TypeList types={[{"name":"keys","type":"`string` \\| `string`[]","description":"The keys to acquire the lock on.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"args","type":"`object`","description":"Additional arguments for acquiring the lock.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"ownerId","type":"`null` \\| `string`","description":"The owner ID for the lock. If specified, only the owner can release the lock or extend its expiration time.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"expire","type":"`number`","description":"The expiration time (in seconds) for the lock. If the lock is already acquired and the owner is the same, the expiration time is extended\nby the value passed. If not specified, the lock does not expire.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider","type":"`string`","description":"The provider name to use for locking. If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"sharedContext","type":"[Context](../../../types/interfaces/types.Context/page.mdx)","description":"A context used to share resources, such as transaction manager, between the application and the module.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"transactionManager","type":"TManager","description":"An instance of a transaction manager of type `TManager`, which is a typed parameter passed to the context to specify the type of the `transactionManager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"manager","type":"TManager","description":"An instance of a manager, typically an entity manager, of type `TManager`, which is a typed parameter passed to the context to specify the type of the `manager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"isolationLevel","type":"`string`","description":"A string indicating the isolation level of the context. Possible values are `READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`, or `SERIALIZABLE`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"enableNestedTransactions","type":"`boolean`","description":"A boolean value indicating whether nested transactions are enabled.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"eventGroupId","type":"`string`","description":"A string indicating the ID of the group to aggregate the events to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"transactionId","type":"`string`","description":"A string indicating the ID of the current transaction.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"messageAggregator","type":"[IMessageAggregator](../../../types/interfaces/types.IMessageAggregator/page.mdx)","description":"An instance of a message aggregator, which is used to aggregate messages to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"requestId","type":"`string`","description":"A string indicating the ID of the current request.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"idempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the current workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"parentStepIdempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the parent workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="acquire"/>

### Returns

<TypeList types={[{"name":"Promise","type":"Promise&#60;void&#62;","optional":false,"defaultValue":"","description":"Resolves when the lock is acquired.","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="acquire"/>

___

## release

This method releases a lock on the given keys. You can optionally pass a provider name to be used for locking.
If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.

If the lock has an owner, you must pass the same owner to release the lock.

### Example

For example, to release a lock on a product with ID `prod_123` for a user with ID `user_123`:

```ts
await lockingModuleService.release("prod_123", {
  ownerId: "user_123"
})
```

In this example, you release the lock on the product with ID `prod_123` for the user with ID `user_123`.

To specify the provider to use for locking, you can pass the provider name in the `args` argument:

```ts
await lockingModuleService.release("prod_123", {
  ownerId: "user_123",
  provider: "lp_my-lock"
})
```

### Parameters

<TypeList types={[{"name":"keys","type":"`string` \\| `string`[]","description":"The keys to release the lock from.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"args","type":"`object`","description":"Additional arguments for releasing the lock.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"ownerId","type":"`null` \\| `string`","description":"The ID of the lock's owner. The lock can be released either if it doesn't have an owner, or \nif its owner ID matches the one passed in this property.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider","type":"`string`","description":"The provider name to use for locking. If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"sharedContext","type":"[Context](../../../types/interfaces/types.Context/page.mdx)","description":"A context used to share resources, such as transaction manager, between the application and the module.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"transactionManager","type":"TManager","description":"An instance of a transaction manager of type `TManager`, which is a typed parameter passed to the context to specify the type of the `transactionManager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"manager","type":"TManager","description":"An instance of a manager, typically an entity manager, of type `TManager`, which is a typed parameter passed to the context to specify the type of the `manager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"isolationLevel","type":"`string`","description":"A string indicating the isolation level of the context. Possible values are `READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`, or `SERIALIZABLE`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"enableNestedTransactions","type":"`boolean`","description":"A boolean value indicating whether nested transactions are enabled.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"eventGroupId","type":"`string`","description":"A string indicating the ID of the group to aggregate the events to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"transactionId","type":"`string`","description":"A string indicating the ID of the current transaction.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"messageAggregator","type":"[IMessageAggregator](../../../types/interfaces/types.IMessageAggregator/page.mdx)","description":"An instance of a message aggregator, which is used to aggregate messages to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"requestId","type":"`string`","description":"A string indicating the ID of the current request.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"idempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the current workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"parentStepIdempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the parent workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="release"/>

### Returns

<TypeList types={[{"name":"Promise","type":"Promise&#60;boolean&#62;","optional":false,"defaultValue":"","description":"Whether the lock was successfully released. If the lock has a different owner than the one passed, the method returns `false`.","expandable":false,"children":[{"name":"boolean","type":"`boolean`","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="release"/>

___

## releaseAll

This method releases all locks. If you specify an owner ID, then all locks that the owner has acquired are released.

You can also pass a provider name to be used for locking. If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.

### Example

For example, to release all locks for a user with ID `user_123`:

```ts
await lockingModuleService.releaseAll({
  ownerId: "user_123"
})
```

In this example, you release all locks for the user with ID `user_123`.

To specify the provider to use for locking, you can pass the provider name in the `args` argument:

```ts
await lockingModuleService.releaseAll({
  ownerId: "user_123",
  provider: "lp_my-lock"
})
```

### Parameters

<TypeList types={[{"name":"args","type":"`object`","description":"Additional arguments for releasing the locks.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"ownerId","type":"`null` \\| `string`","description":"The ID of a lock owner. If specified, all locks that the owner has acquired are released.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"provider","type":"`string`","description":"The provider name to use for locking. If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.","optional":true,"defaultValue":"","expandable":false,"children":[]}]},{"name":"sharedContext","type":"[Context](../../../types/interfaces/types.Context/page.mdx)","description":"A context used to share resources, such as transaction manager, between the application and the module.","optional":true,"defaultValue":"","expandable":false,"children":[{"name":"transactionManager","type":"TManager","description":"An instance of a transaction manager of type `TManager`, which is a typed parameter passed to the context to specify the type of the `transactionManager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"manager","type":"TManager","description":"An instance of a manager, typically an entity manager, of type `TManager`, which is a typed parameter passed to the context to specify the type of the `manager`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"isolationLevel","type":"`string`","description":"A string indicating the isolation level of the context. Possible values are `READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`, or `SERIALIZABLE`.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"enableNestedTransactions","type":"`boolean`","description":"A boolean value indicating whether nested transactions are enabled.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"eventGroupId","type":"`string`","description":"A string indicating the ID of the group to aggregate the events to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"transactionId","type":"`string`","description":"A string indicating the ID of the current transaction.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"messageAggregator","type":"[IMessageAggregator](../../../types/interfaces/types.IMessageAggregator/page.mdx)","description":"An instance of a message aggregator, which is used to aggregate messages to be emitted at a later point.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"requestId","type":"`string`","description":"A string indicating the ID of the current request.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"idempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the current workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]},{"name":"parentStepIdempotencyKey","type":"`string`","description":"A string indicating the idempotencyKey of the parent workflow execution.","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="releaseAll"/>

### Returns

<TypeList types={[{"name":"Promise","type":"Promise&#60;void&#62;","optional":false,"defaultValue":"","description":"This method releases all locks. If you specify an owner ID, then all locks that the owner has acquired are released.\n\nYou can also pass a provider name to be used for locking. If no provider is passed, the default provider (in-memory or the provider configuerd in `medusa-config.ts`) will be used.","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="releaseAll"/>
