

# Lock:transactionid
<a name="wait-event.locktransactionid"></a>

`Lock:transactionid` 이벤트는 트랜잭션이 행 수준 잠금을 대기 중일 때 발생합니다.

**Topics**
+ [지원되는 엔진 버전](#wait-event.locktransactionid.context.supported)
+ [컨텍스트](#wait-event.locktransactionid.context)
+ [대기 증가의 가능한 원인](#wait-event.locktransactionid.causes)
+ [작업](#wait-event.locktransactionid.actions)

## 지원되는 엔진 버전
<a name="wait-event.locktransactionid.context.supported"></a>

이 대기 이벤트 정보는 모든 RDS for PostgreSQL 버전에서 지원됩니다.

## 컨텍스트
<a name="wait-event.locktransactionid.context"></a>

이벤트 `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` 명령을 차단할 수 있습니다.

## 대기 증가의 가능한 원인
<a name="wait-event.locktransactionid.causes"></a>

이 이벤트가 정상보다 많이 나타나는 경우 일반적으로 원인은 다음 조건과 결합된 `UPDATE`, `SELECT … FOR UPDATE`, 또는 `SELECT … FOR KEY SHARE` 문입니다.

**Topics**
+ [높은 동시성](#wait-event.locktransactionid.concurrency)
+ [트랜잭션의 유휴 상태](#wait-event.locktransactionid.idle)
+ [장기 실행 트랜잭션](#wait-event.locktransactionid.long-running)

### 높은 동시성
<a name="wait-event.locktransactionid.concurrency"></a>

RDS for PostgreSQL은 세분화된 행 수준 잠금 의미 체계를 사용할 수 있습니다. 다음 조건이 충족되면 행 수준 충돌 확률이 높아집니다.
+ 동일한 행에 대해 높은 동시 워크로드가 경합됩니다.
+ 동시성이 증가합니다.

### 트랜잭션의 유휴 상태
<a name="wait-event.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="wait-event.locktransactionid.long-running"></a>

오랫동안 실행되는 트랜잭션은 오랜 시간 동안 잠금을 얻습니다. 이러한 장기 잠금은 다른 트랜잭션의 실행을 차단할 수 있습니다.

## 작업
<a name="wait-event.locktransactionid.actions"></a>

행 잠금은 `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)

### 동시성에 대응
<a name="wait-event.locktransactionid.actions.problem"></a>

동시성이 문제가 되는 경우 다음 기술 중 하나를 시도해 보세요.
+ 애플리케이션의 동시성을 낮춥니다. 예를 들어 활성 세션 수를 줄일 수 있습니다.
+ 연결 풀을 구현합니다. RDS 프록시로 연결을 풀링하는 방법에 대한 자세한 내용은 [ Amazon RDS Proxy](rds-proxy.md) 섹션을 참조하세요.
+ `UPDATE` 문과 `SELECT … FOR UPDATE` 문의 경쟁 방지를 위한 애플리케이션 또는 데이터 모델을 설계하세요. `SELECT … FOR KEY SHARE` 문으로 액세스하는 외래 키 수를 줄일 수도 있습니다.

### 유휴 트랜잭션에 대응
<a name="wait-event.locktransactionid.actions.find-blocker"></a>

`pg_stat_activity.state`가 `idle in transaction`을 나타낸다면, 다음 전략을 시도해 보세요.
+ 가능하면 자동 커밋을 켭니다. 이 접근 방식은 트랜잭션이 `COMMIT`이나 `ROLLBACK`을 대기하는 동안 다른 트랜잭션을 차단하는 것을 방지합니다.
+ `COMMIT`, `ROLLBACK`, 또는 `END`가 누락된 코드 경로 검색
+ 애플리케이션의 예외 처리 논리에 항상 유효한 `end of transaction`으로 향하는 경로가 있는지 확인하세요.
+ `COMMIT` 및 `ROLLBACK`과의 트랜잭션을 종료한 후 애플리케이션이 쿼리 결과를 처리하는지 확인하세요.

### 장기 실행 트랜잭션에 대응
<a name="wait-event.locktransactionid.actions.concurrency"></a>

장기 실행 트랜잭션으로 인해 `Lock:transactionid`가 자주 발생하는 경우 다음 전략을 시도해 보세요.
+ 장기 실행 트랜잭션에서 행 잠금을 차단합니다.
+ 가능하면 자동 커밋을 구현하여 쿼리 길이를 제한합니다.