

# Lock:transactionid
<a name="apg-waits.locktransactionid"></a>

`Lock:transactionid`イベントは、トランザクションが行レベルのロックを待っているときに発生します。

**Topics**
+ [サポート対象エンジンバージョン](#apg-waits.locktransactionid.context.supported)
+ [Context](#apg-waits.locktransactionid.context)
+ [待機時間が増加する原因の可能性](#apg-waits.locktransactionid.causes)
+ [アクション](#apg-waits.locktransactionid.actions)

## サポート対象エンジンバージョン
<a name="apg-waits.locktransactionid.context.supported"></a>

この待機イベント情報は、Aurora PostgreSQL のすべてのバージョンでサポートされています。

## Context
<a name="apg-waits.locktransactionid.context"></a>

イベント`Lock:transactionid`は、トランザクションが、同時に実行されているトランザクションにすでに付与された行レベルのロックを取得しようとすると発生します。を示すセッションは、`Lock:transactionid`待機イベントがこのロックのためにブロックされていることを示します。`COMMIT`または`ROLLBACK`ステートメントでブロックされているトランザクションの完了後、ブロックされたトランザクションを続行できます。

Aurora PostgreSQL のマルチバージョン同時実行制御セマンティクスは、リーダーがライターを、ライターがリーダーをブロックしないことを保証します。行レベルの競合が発生するには、ブロックおよびブロックされたトランザクションで、次のタイプの競合するステートメントを発行する必要があります。
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

ステートメント`SELECT … FOR KEY SHARE`は特殊なケースです。データベースは、レファレンスの整合性のパフォーマンスを最適化するために、`FOR KEY SHARE`節を使用します。行に対する行レベルロックは、行を参照している他のテーブルの`INSERT`、`UPDATE`、`DELETE`コマンドをブロックできます。

## 待機時間が増加する原因の可能性
<a name="apg-waits.locktransactionid.causes"></a>

このイベントが通常よりも頻繁に発生する場合、通常は`UPDATE`、`SELECT … FOR UPDATE`、または`SELECT … FOR KEY SHARE`ステートメントが以下の条件と組み合わさることが原因です。

**Topics**
+ [同時実行数が多い](#apg-waits.locktransactionid.concurrency)
+ [トランザクションでのアイドル状態](#apg-waits.locktransactionid.idle)
+ [トランザクションの実行時間が長い](#apg-waits.locktransactionid.long-running)

### 同時実行数が多い
<a name="apg-waits.locktransactionid.concurrency"></a>

Aurora PostgreSQL は、きめ細かい行レベルのロックセマンティクスを使用できます。以下の条件が満たされると、行レベルの同時実行が発生する可能性が高くなります。
+ 同時性の高いワークロードは、同じ行で同時実行します。
+ 同時実行数が増加します。

### トランザクションでのアイドル状態
<a name="apg-waits.locktransactionid.idle"></a>

時々、`pg_stat_activity.state`列には`idle in transaction`値が表示されます。この値は、トランザクションをスタートしていても、まだ`COMMIT`または`ROLLBACK`を発行していないセッションに表示されます。`pg_stat_activity.state`値が`active`ではない場合、`pg_stat_activity`に表示されるクエリは、実行を終了した最新のクエリになります。ブロックされているセッションは、開いているトランザクションがロックを保持しているため、クエリを積極的に処理しません。

アイドル状態のトランザクションが行レベルロックを取得した場合は、他のセッションがそのロックを取得するのを妨害する可能性があります。この状態は、待機イベント`Lock:transactionid`の頻発につながります。問題を診断するには、`pg_stat_activity`そして`pg_locks`からの出力を検証します。

### トランザクションの実行時間が長い
<a name="apg-waits.locktransactionid.long-running"></a>

実行時間が長いトランザクションは、長時間ロックされます。これらの長時間のロックは、他のトランザクションの実行をブロックすることがあります。

## アクション
<a name="apg-waits.locktransactionid.actions"></a>

行ロックは`UPDATE`、`SELECT … FOR UPDATE`、または`SELECT … FOR KEY SHARE`ステートメント間の競合です。解決策を試す前に、これらのステートメントが同じ行で実行されているかどうかを調べます。この情報をもとに、次のセクションで説明する戦略を選択してください。

**Topics**
+ [同時実行数の多さに対応](#apg-waits.locktransactionid.actions.problem)
+ [アイドル状態のトランザクションに対応する](#apg-waits.locktransactionid.actions.find-blocker)
+ [長時間実行されるトランザクションへの対応](#apg-waits.locktransactionid.actions.concurrency)

### 同時実行数の多さに対応
<a name="apg-waits.locktransactionid.actions.problem"></a>

同時実行数が問題になる場合は、以下から 1 つの方法を試行します。
+ アプリケーションの同時実行数を減らします。例えば、アクティブなセッションの数を減らします。
+ 接続プールを実装します。RDS プロキシを使用して接続をプールする方法については、「[Amazon RDS Proxy for Aurora](rds-proxy.md)」を参照してください。
+ アプリケーションまたはデータモデルを設計し、`UPDATE`および`SELECT … FOR UPDATE`ステートメントの競合を避けてください。また、`SELECT … FOR KEY SHARE`ステートメントにアクセスされる外部キーの数を減らすこともできます。

### アイドル状態のトランザクションに対応する
<a name="apg-waits.locktransactionid.actions.find-blocker"></a>

`pg_stat_activity.state`が`idle in transaction`を示している場合は、以下の方法を使用します。
+ 可能な限り、オートコミットをオンにします。この方法では、`COMMIT`または`ROLLBACK`を待っている間に、トランザクションが他のトランザクションをブロックすることを防ぎます。
+ `COMMIT`、`ROLLBACK`、または`END`が不足しているコードパスを検索します。
+ アプリケーションの例外処理ロジックに、常に有効な`end of transaction`へのパスが設定されていることを確認してください。
+ `COMMIT`または`ROLLBACK`でトランザクションを完了した後、アプリケーションがクエリの結果を処理することを確認します。

### 長時間実行されるトランザクションへの対応
<a name="apg-waits.locktransactionid.actions.concurrency"></a>

長時間実行されるトランザクションが`Lock:transactionid`の発生を頻繁に引き起こす場合、以下の方法を試します。
+ 長時間実行されるトランザクションが行をロックしないようにします。
+ 可能であれば、オートコミットを実装してクエリの長さを制限します。