# Lock (/zh-CN/api-reference/rtm/unity/lock)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

临界资源一次只能供一个进程使用，如果不同的进程之间共享了某个临界资源，则各进程需要采取互斥的方式来防止彼此干扰。RTM 提供一整套 Lock 的方案，通过控制分布式系统的不同进程，你可以解决用户在访问共享资源时的竞争问题。

:::info[信息]
客户端 SDK 具备设置、删除、撤销锁的能力，我们建议你根据实际业务需求控制端侧对锁的操作权限。
:::

## SetLockAsync [#setlockasync]

### 接口描述 [#接口描述]

你需要配置锁的名称、过期时间 TTL 等属性，然后调用 `SetLockAsync` 方法进行配置。配置成功后，频道中的所有用户会收到 `SET` 类型的 `OnLockEvent` 事件通知，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)。

### 接口方法 [#接口方法]

你可以通过以下方式调用 `SetLockAsync` 方法：

```csharp
RtmResult<SetLockResult> rtmClient.GetLock().SetLockAsync(
    string channelName,
    RTM_CHANNEL_TYPE channelType,
    string lockName,
    int ttl
    );
```

|     参数      |     类型      | 是否必填 |       默认值        | 描述               |
| ---------- | --------------- | ----- | ---- | ---------- |
| `channelName` |    string     |   必填   |          -          | 频道名称。         |
| `channelType` | `RTM_CHANNEL_TYPE` |   必填   | `STREAM` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。           |
|  `lockName`   |    string     |   必填   |          -          | Lock 的名称。      |
|     `ttl`     |    Number     |   选填   |        `10`         | 锁的过期时间，单位为秒，取值范围为 [10,300]。当使用这把锁的用户掉线时，如果用户在过期时间之内重新回到频道，则该用户依旧可以使用锁；否则，该用户的锁会被释放，监听了 `OnLockEvent` 事件通知的用户会收到 `RELEASED` 事件。 |

### 基本用法 [#基本用法]

```cs
var (status,response) = await rtmClient.GetLock().SetLockAsync("Chat_room", RTM_CHANNEL_TYPE.MESSAGE, "lock1", 30);
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, ErrorCode {1}, because of: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log(string.Format("Set Lock at Channel:{0} with Channel Type {1} success! Lock name is {2}", response.ChannelName, response.ChannelType, response.LockName));
}
```

### 返回值 [#返回值]

`SetLockAsync` 操作返回一个 `RtmResult<SetLockResult>` 类型数据结构的返回值，其中包含：

|    属性    |      类型      | 描述        |
| ------- | ---------------- | ----------- |
|  `Status`  |  `RtmStatus`  | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。 |
| `Response` | `SetLockResult` | 操作成功后，返回一个 `SetLockResult` 类型的数据结构。         |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`SetLockResult` 包含以下属性：

|     属性      |     类型      | 描述     |
| ---------- | --------------- | ------ |
| `ChannelName` |    string     | 频道名称。                   |
| `ChannelType` | `RTM_CHANNEL_TYPE` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `LockName`   |    string     | Lock 的名称。                |

## AcquireLockAsync [#acquirelockasync]

### 接口描述 [#接口描述-1]

成功配置 Lock 后，你可以在客户端调用 `AcquireLockAsync` 方法获取锁的使用权。成功获取锁后，频道中的其他用户会收到 `ACQUIRED` 类型的 `OnLockEvent` 事件通知，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)。

### 接口方法 [#接口方法-1]

你可以通过以下方式调用 `AcquireLockAsync` 方法：

```csharp
RtmResult<AcquireLockResult> rtmClient.GetLock().AcquireLockAsync(
    string channelName,
    RTM_CHANNEL_TYPE channelType,
    string lockName,
    bool retry
    );
```

|     参数      |     类型      | 是否必填 |       默认值        | 描述     |
| ---------- | --------------- | ----- | ---- | ------ |
| `channelName` |    string     |   必填   |          -          | 频道名称。                   |
| `channelType` | `RTM_CHANNEL_TYPE` |   必填   | `STREAM` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `lockName`   |    string     |   必填   |          -          | Lock 的名称。                |
|    `retry`    |     bool      |   选填   |        false        | 在获取失败后是否继续尝试，直到成功获取或退出频道为止。          |

### 接口方法 [#接口方法-2]

```cs
var (status,response) = await rtmClient.GetLock().AcquireLockAsync("Chat_room", RTM_CHANNEL_TYPE.MESSAGE, "lock1", false);
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, ErrorCode: {1}, due to: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log(string.Format("Acquire Lock at Channel:{0} with Channel Type {1} success! Lock name is {2}", response.ChannelName, response.ChannelType, response.LockName));
}
```

### 返回值 [#返回值-1]

`AcquireLockAsync` 操作返回一个 `RtmResult<AcquireLockResult>` 类型数据结构的返回值，其中包含：

|    属性    |        类型        | 描述        |
| ------- | --- | ----------- |
|  `Status`  |    `RtmStatus`    | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。 |
| `Response` | `AcquireLockResult` | 操作成功后，返回一个 `AcquireLockResult` 类型的数据结构。     |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`AcquireLockResult` 包含以下属性：

|      属性      |     类型      | 描述              |
| ----------- | --------------- | ---------- |
| `ChannelName`  |    string     | 频道名称。        |
| `ChannelType`  | `RTM_CHANNEL_TYPE` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。             |
|   `LockName`   |    string     | Lock 的名称。     |

## ReleaseLockAsync [#releaselockasync]

### 接口描述 [#接口描述-2]

当用户不再需要持有某把锁时，用户可以在客户端调用 `ReleaseLockAsync` 方法主动释放锁。成功释放后，频道中的其他用户会收到 `RELEASED` 类型的 `OnLockEvent` 事件，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)。

此时，如果其他用户想要获取该锁，可以在客户端调用 `AcquireLockAsync` 方法参与竞争。新参与获取锁的用户和之前设置 `retry` 属性自动尝试获取锁的用户的竞争优先级相同。

### 接口方法 [#接口方法-3]

你可以通过以下方式调用 `ReleaseLockAsync` 方法：

```csharp
RtmResult<ReleaseLockResult> rtmClient.GetLock().ReleaseLockAsync(
    string channelName,
    RTM_CHANNEL_TYPE channelType,
    string lockName
    );
```

|     参数      |     类型      | 是否必填 |       默认值        | 描述     |
| ---------- | --------------- | ----- | ---- | ------ |
| `channelName` |    string     |   必填   |          -          | 频道名称。                   |
| `channelType` | `RTM_CHANNEL_TYPE` |   必填   | `STREAM` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `lockName`   |    string     |   必填   |          -          | Lock 的名称。                |

### 基本用法 [#基本用法-1]

```cs
var (status,response) = await rtmClient.GetLock().ReleaseLockAsync("Chat_room", RTM_CHANNEL_TYPE.MESSAGE, "lock1");
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, ErrorCode: {1}, due to: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log(string.Format("Release Lock at Channel:{0} with Channel Type {1} success! Lock name is {2}", response.ChannelName, response.ChannelType, response.LockName));
}
```

### 返回值 [#返回值-2]

`ReleaseLockAsync` 操作返回一个 `RtmResult<ReleaseLockResult>` 类型数据结构的返回值，其中包含：

|    属性    |        类型        | 描述        |
| ------- | --- | ----------- |
|  `Status`  |    `RtmStatus`    | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。 |
| `Response` | `ReleaseLockResult` | 操作成功后，返回一个 `ReleaseLockResult` 类型的数据结构。     |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`ReleaseLockResult` 包含以下属性：

|     属性      |     类型      | 描述     |
| ---------- | --------------- | ------ |
| `ChannelName` |    string     | 频道名称。                   |
| `ChannelType` | `RTM_CHANNEL_TYPE` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `LockName`   |    string     | Lock 的名称。                |

## RevokeLockAsync [#revokelockasync]

### 接口描述 [#接口描述-3]

当锁被占用时，为保证你的业务不受影响，你可能需要收回该锁，并让其他用户有机会获取该锁。调用 `RevokeLockAsync` 收回被占用的锁。成功收回后，频道中的所有用户会收到 `RELEASED` 类型的 `OnLockEvent` 事件，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)。

此时，如果其他用户想要获取该锁，可以在客户端调用 `AcquireLockAsync` 方法参与竞争。新参与获取锁的用户和之前设置 `retry` 属性自动尝试获取锁的用户的竞争优先级相同。

### 接口方法 [#接口方法-4]

你可以通过以下方式调用 `RevokeLockAsync` 方法：

```csharp
RtmResult<RevokeLockResult> rtmClient.GetLock().RevokeLockAsync(
    string channelName,
    RTM_CHANNEL_TYPE channelType,
    string lockName,
    string owner
    );
```

|     参数      |     类型      | 是否必填 |       默认值        | 描述     |
| ---------- | --------------- | ----- | ---- | ------ |
| `channelName` |    string     |   必填   |          -          | 频道名称。                   |
| `channelType` | `RTM_CHANNEL_TYPE` |   必填   | `STREAM` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `lockName`   |    string     |   必填   |          -          | Lock 的名称。                |
|    `owner`    |    string     |   必填   |          -          | 拥有锁的用户 ID。            |

### 基本用法 [#基本用法-2]

```cs
var (status,response) = await rtmClient.GetLock().RevokeLockAsync("Chat_room", RTM_CHANNEL_TYPE.MESSAGE, "lock1","Tony");
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, ErrorCode: {1}, due to: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log(string.Format("RevokeLock at Channel:{0} with Channel Type {1} success! Lock name is {2}", response.ChannelName, response.ChannelType, response.LockName));
}
```

### 返回值 [#返回值-3]

`RevokeLockAsync` 操作返回一个 `RtmResult<RevokeLockResult>` 类型数据结构的返回值，其中包含：

|  属性  |  类型  | 描述               |
| ------------ | ---------------- | ------ |
| `Status`      |      `RtmStatus`      | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。 |
| `Response`      | `RevokeLockResult` | 操作成功后，返回一个 `RevokeLockResult` 类型的数据结构。 |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`RevokeLockResult` 包含以下属性：

|     属性      |     类型      | 描述     |
| ---------- | --------------- | ------ |
| `ChannelName` |    string     | 频道名称。                   |
| `ChannelType` | `RTM_CHANNEL_TYPE` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `LockName`   |    string     | Lock 的名称。                |

## GetLocksAsync [#getlocksasync]

### 接口描述 [#接口描述-4]

如果你需要查询频道中锁的数量、名称、使用者、过期时间等信息，在客户端调用 `GetLocksAsync` 方法。

### 接口方法 [#接口方法-5]

你可以通过以下方式调用 `GetLocksAsync` 方法：

```cs
RtmResult<GetLocksResult> rtmClient.GetLock().GetLocksAsync(
    string channelName,
    RTM_CHANNEL_TYPE channelType
    );
```

|     属性      |     类型      | 是否必填 |       默认值        | 描述     |
| ---------- | --------------- | ----- | ---- | ------ |
| `channelName` |    string     |   必填   |          -          | 频道名称。                   |
| `channelType` | `RTM_CHANNEL_TYPE` |   必填   | `STREAM` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |

### 基本用法 [#基本用法-3]

```cs
var (status,response) = await rtmClient.GetLock().GetLockAsync("Chat_room", RTM_CHANNEL_TYPE.MESSAGE);
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, The error code is {1}, because of: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log(string.Format("Get Lock at Channel:{0} with Channel Type {1} success! ", response.ChannelName, response.ChannelType));
}
```

### 返回值 [#返回值-4]

`GetLocksAsync` 操作返回一个 `RtmResult<GetLockResult>` 类型数据结构的返回值，其中包含：

|    属性    |      类型      | 描述        |
| ------- | ---------------- | ----------- |
|  `Status`  |  `RtmStatus`  | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。 |
| `Response` | `GetLockResult` | 操作成功后，返回一个 `GetLockResult` 类型的数据结构。         |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`GetLockResult` 包含以下属性：

|       属性       |     类型      | 描述     |
| ------------- | --------------- | ------ |
|  `ChannelName`   |    string     | 频道名称。                   |
|  `ChannelType`   | `RTM_CHANNEL_TYPE` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
| `LockDetailList` |   `LockDetail[]`   | 锁详情数组。                 |

`LockDetail` 包含以下属性：

|    属性    |  类型  | 描述               |
| ------- | --- | ---------- |
| `LockName` | string | Lock 的名称。      |
|  `owner`   | string | 拥有锁的用户 ID。  |
|   `ttl`    | number | 锁的过期时间。当使用这把锁的用户掉线时，如果用户在过期时间之内重新回到频道，则该用户依旧可以使用锁；否则，该用户的锁会被释放，监听了 `OnLockEvent` 事件通知的用户会收到 `RELEASED` 事件。 |

## RemoveLockAsync [#removelockasync]

### 接口描述 [#接口描述-5]

如果你不再需要频道中的某把锁，你可以调用 `RemoveLockAsync` 方法删除该锁。成功删除锁后，频道中的所有用户会收到 `REMOVED` 类型的 `OnLockEvent` 事件通知，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)。

### 接口方法 [#接口方法-6]

你可以通过以下方式调用 `RemoveLockAsync` 方法：

```cs
RtmResult<RemoveLockResult> rtmClient.GetLock().RemoveLockAsync(
    string channelName,
    RTM_CHANNEL_TYPE channelType,
    string lockName
    );
```

|     参数      |     类型      | 是否必填 |       默认值        | 描述     |
| ---------- | --------------- | ----- | ---- | ------ |
| `channelName` |    string     |   必填   |          -          | 频道名称。                   |
| `channelType` | `RTM_CHANNEL_TYPE` |   必填   | `STREAM` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `lockName`   |    string     |   必填   |          -          | Lock 的名称。                |

### 基本用法 [#基本用法-4]

```cs
var (status,response) = await rtmClient.GetLock().RemoveLockAsync("Chat_room", RTM_CHANNEL_TYPE.MESSAGE, "lock1");
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, The error code is {1}, because of: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log(string.Format("Remove Lock{0} at Channel:{1} with Channel Type {2} success! ",response.LocklName, response.ChannelName, response.ChannelType));
}
```

### 返回值 [#返回值-5]

`RemoveLockAsync` 操作返回一个 `RtmResult<RemoveLockResult>` 类型数据结构的返回值，其中包含：

|    属性    |       类型        | 描述        |
| ------- | ----- | ----------- |
|  `Status`  |   `RtmStatus`    | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。 |
| `Response` | `RemoveLockResult` | 操作成功后，返回一个 `RemoveLockResult` 类型的数据结构。      |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`RemoveLockResult` 包含以下属性：

|     属性      |     类型      | 描述     |
| ---------- | --------------- | ------ |
| `ChannelName` |    string     | 频道名称。                   |
| `ChannelType` | `RTM_CHANNEL_TYPE` | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
|  `LockName`   |    string     | Lock 的名称。                |
