> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Lock SDK for Game Engine API Reference

Specifications of models and API references for GS2-Lock SDK for Game Engine



## Models

### EzMutex

Mutex

The mutex provided by GS2 is a type of re-entrant lock.

When acquiring a lock, a transaction ID is specified, and the lock can be acquired again only if the same transaction ID is specified.
Since it has a reference counter, the same number of unlock operations are required when releasing it.

|  | Type | Condition | Required | Default | Value Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| mutexId | string |  | * |  |  ~ 1024 chars | Mutex GRN<br>* Set automatically by the server |
| propertyId | string |  | ✓ |  |  ~ 1024 chars | Property ID<br>An identifier for the resource to be locked, determining which resource the lock is protecting.<br>When multiple processes need exclusive access to the same resource, they should specify the same property ID. |
| transactionId | string |  | ✓ |  |  ~ 256 chars | Transaction ID<br>An identifier for the transaction acquiring the lock. This ID is used to implement re-entrant locking behavior:<br>if a lock request specifies the same transaction ID as the current lock holder, the lock is successfully acquired again and the reference count is incremented.<br>A lock request with a different transaction ID will be rejected while the lock is held. |
| ttlAt | long |  |  | Absolute time 1 hour after the current time |  | Expiration datetime<br>Unix time, milliseconds |

**Related methods:**
get - Get Mutex status
lock - Acquire Lock
unlock - Release Lock


---

## Methods

### get

Get Mutex status

#### Request

|  | Type | Condition | Required | Default | Value Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128 chars | Namespace name<br>Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). |
| propertyId | string |  | ✓|  |  ~ 1024 chars | Property ID<br>An identifier for the resource to be locked, determining which resource the lock is protecting.<br>When multiple processes need exclusive access to the same resource, they should specify the same property ID. |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | Type | Description |
| --- | --- | --- |
| item | [EzMutex](#ezmutex) | Mutex|

#### Implementation Example




**Unity (UniTask)**
```csharp
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Lock->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mutex(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```


##### Value change event handling




**Unity (UniTask)**
```csharp
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Lock->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mutex(
        "property-0001" // propertyId
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Lock::Model::FMutex> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

```


**⚠️ Warning**

This event is triggered when the value stored in the SDK's local cache changes.

The local cache is updated only when executing the SDK's API, or by executing stamp sheets via GS2-Distributor with GS2-Gateway notification enabled, or by executing jobs via GS2-JobQueue with GS2-Gateway notification enabled.

Therefore, callbacks will not be invoked if the value is changed in any other way.

---

### lock

Acquire Lock

Locks the resource with the `property ID` for the number of seconds specified by ttl.
The `transaction ID` must be specified when locking.
Acquisition of a lock on the same `property ID` by a different `transaction ID` will fail.
If the lock acquisition request is from the same transaction, the reference counter is increased.

#### Request

|  | Type | Condition | Required | Default | Value Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128 chars | Namespace name<br>Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). |
| propertyId | string |  | ✓|  |  ~ 1024 chars | Property ID<br>An identifier for the resource to be locked, determining which resource the lock is protecting.<br>When multiple processes need exclusive access to the same resource, they should specify the same property ID. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| transactionId | string |  | ✓|  |  ~ 256 chars | Transaction ID<br>An identifier for the transaction acquiring the lock. This ID is used to implement re-entrant locking behavior:<br>if a lock request specifies the same transaction ID as the current lock holder, the lock is successfully acquired again and the reference count is incremented.<br>A lock request with a different transaction ID will be rejected while the lock is held. |
| ttl | long |  | ✓|  | 0 ~ 9223372036854775805 | Duration of lock acquisition (seconds) |

#### Result

|  | Type | Description |
| --- | --- | --- |
| item | [EzMutex](#ezmutex) | Mutex|

#### Implementation Example




**Unity (UniTask)**
```csharp
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    var result = await domain.LockAsync(
        transactionId: "transaction-0001",
        ttl: 100000L
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    var future = domain.LockFuture(
        transactionId: "transaction-0001",
        ttl: 100000L
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Lock->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mutex(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Lock(
        "transaction-0001", // transactionId
        100000L // ttl
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```


---

### unlock

Release Lock

The lock must be released from the same `transaction ID`.
If the lock is re-entered when the lock is acquired, the lock is released the same number of times, and the actual release occurs when the reference counter reaches zero.

#### Request

|  | Type | Condition | Required | Default | Value Limits | Description |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128 chars | Namespace name<br>Unique Namespace name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.). |
| propertyId | string |  | ✓|  |  ~ 1024 chars | Property ID<br>An identifier for the resource to be locked, determining which resource the lock is protecting.<br>When multiple processes need exclusive access to the same resource, they should specify the same property ID. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| transactionId | string |  | ✓|  |  ~ 256 chars | Transaction ID<br>An identifier for the transaction acquiring the lock. This ID is used to implement re-entrant locking behavior:<br>if a lock request specifies the same transaction ID as the current lock holder, the lock is successfully acquired again and the reference count is incremented.<br>A lock request with a different transaction ID will be rejected while the lock is held. |

#### Result

|  | Type | Description |
| --- | --- | --- |
| item | [EzMutex](#ezmutex) | Mutex|

#### Implementation Example




**Unity (UniTask)**
```csharp
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    var result = await domain.UnlockAsync(
        transactionId: "transaction-0001"
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Lock.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Mutex(
        propertyId: "property-0001"
    );
    var future = domain.UnlockFuture(
        transactionId: "transaction-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Lock->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Mutex(
        "property-0001" // propertyId
    );
    const auto Future = Domain->Unlock(
        "transaction-0001" // transactionId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```


---



