

# Lock:transactionid


当事务正在等待行级锁定时，会发生 `Lock:transactionid` 事件。

**Topics**
+ [

## 支持的引擎版本
](#wait-event.locktransactionid.context.supported)
+ [

## 上下文
](#wait-event.locktransactionid.context)
+ [

## 等待次数增加的可能原因
](#wait-event.locktransactionid.causes)
+ [

## 操作
](#wait-event.locktransactionid.actions)

## 支持的引擎版本


RDS for PostgreSQL 的所有版本均支持此等待事件信息。

## 上下文


当事务试图获取已被授予同时运行的事务的行级锁时，会发生事件 `Lock:transactionid`。显示 `Lock:transactionid` 等待事件的会话因此锁定被阻止。当阻止事务在 `COMMIT` 或 `ROLLBACK` 语句中结束后，被阻止的事务可以继续进行。

RDS for PostgreSQL 的多版本并发控制语义保证读取器不会阻止写入器，写入器也不会阻止读取器。为了发生行级冲突，正在阻止和已阻止的事务必须发出以下类型的冲突语句：
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

语句 `SELECT … FOR KEY SHARE` 是一种特殊情况。数据库使用子句 `FOR KEY SHARE` 以优化参照完整性的性能。一行上的行级锁定可以组织引用该行的其他表上的 `INSERT`、`UPDATE` 和 `DELETE` 命令。

## 等待次数增加的可能原因


当此事件出现频率超过正常时，原因通常是 `UPDATE`、`SELECT … FOR UPDATE` 或 `SELECT … FOR KEY SHARE` 语句结合以下条件。

**Topics**
+ [

### 高并发性
](#wait-event.locktransactionid.concurrency)
+ [

### 空闲事务
](#wait-event.locktransactionid.idle)
+ [

### 长时间运行的事务
](#wait-event.locktransactionid.long-running)

### 高并发性


RDS for PostgreSQL 可以使用细粒度的行级锁定语义。满足以下条件时，行级冲突的可能性会增加：
+ 高度并发的工作负载争用相同的行。
+ 并发性增加。

### 空闲事务


有时，`pg_stat_activity.state` 列会显示值 `idle in transaction`。对于已开始事务但尚未发布 `COMMIT` 或 `ROLLBACK` 的会话，会显示此值。如果 `pg_stat_activity.state` 值不为 `active`，`pg_stat_activity` 中显示的查询是完成运行的最新版本。阻止会话没有主动处理查询，因为未完成的事务持有锁定。

如果空闲事务获得了行级锁，则可能会阻止其他会话获取它。这种情况导致等待事件 `Lock:transactionid` 频繁发生。要诊断问题，请检查来自的 `pg_stat_activity` 和 `pg_locks` 的输出。

### 长时间运行的事务


长时间运行的事务会获得很长一段时间的锁定。这些长期保留的锁定可以阻止其他事务运行。

## 操作


行锁定是 `UPDATE`、`SELECT … FOR UPDATE` 或 `SELECT … FOR KEY SHARE` 语句之间发生的冲突。在尝试解决方案之前，请先了解这些语句何时在同一行上运行。使用此信息选择以下各部分所述的策略。

**Topics**
+ [

### 响应高并发
](#wait-event.locktransactionid.actions.problem)
+ [

### 回应空闲事务
](#wait-event.locktransactionid.actions.find-blocker)
+ [

### 响应长期运行的事务
](#wait-event.locktransactionid.actions.concurrency)

### 响应高并发


如果并发性是问题，请尝试以下方法之一：
+ 降低应用程序中的并发率。例如，减少活动会话的数量。
+ 实施连接池。要了解如何使用 RDS 代理进行池连接，请参阅 [Amazon RDS 代理](rds-proxy.md)。
+ 设计应用程序或数据模型以避免争用 `UPDATE` 和 `SELECT … FOR UPDATE` 语句。您还可以减少 `SELECT … FOR KEY SHARE` 语句访问的外键的数量。

### 回应空闲事务


如果 `pg_stat_activity.state` 显示 `idle in transaction`，请使用以下策略：
+ 尽可能开启自动提交。这种方法可防止事务在等待 `COMMIT` 或 `ROLLBACK` 时阻止其他事务。
+ 搜索缺失 `COMMIT`、`ROLLBACK` 或 `END` 的代码路径。
+ 确保应用程序中的异常处理逻辑始终具有通向有效 `end of transaction` 的路径。
+ 确保您的应用程序在结束与`COMMIT` 或 `ROLLBACK` 的事务后处理查询结果。

### 响应长期运行的事务


如果长时间运行的事务导致频繁发生 `Lock:transactionid`，请尝试以下策略：
+ 在长时间运行的事务中保持行锁定。
+ 尽可能通过实现自动提交来限制查询的长度。