개발/SQL

select for update

walxx__ 2023. 1. 4. 23:41

여러 트랜잭션에서 동일한 데이터에 엑세스에 접근을 할 때, 데이터의 꼬임을 방지 하기 위해 사용.

선택된 행에 lock을 설정하는 기능

 

옵션

// 예시
select * from admin where id = 1 for update; // lock이 걸려 있는 상태에서는 무작정 기다린다.
select * from admin where id = 1 for update nowait; // lock이 걸려 있는 상태에서는 에러처리를 한다.

 

Example

각 다른 트랙잭션에서 동시에 아래 3개의 select for update 쿼리를 실행 했을 때?

select * from admin where id = 1 for update; // 실행 commit이 될 때까지, Lock을 잡고 있음
select * from admin where id = 1 for update; // 위의 쿼리와 동일한 행이므로, Lock이 풀린 이후에 실행.
select * from admin where id = 2 for update; // 위의 쿼리와 다른 행이므로, 바로 실행

 

각 다른 트랙잭션에서 동시에 select for update와 select 구문을 실행 했을 때?

select * from admin where id = 1 for update; // 실행 commit이 될 때까지, Lock을 잡고 있음
select * from admin where id = 1; // 실행

 

각 다른 트랜잭션에서 동시에 select for update와 update 구문을 실행 했을 때?

select * from admin where id = 1 for update; // 실행 commit이 될 때까지, Lock을 잡고 있음
update admin set name = '이름' where id = 1; // Lock이 풀릴때까지 대기

 

Code Level

//jpa
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT o FROM admin a WHERE a.id = :id")
fun findByIdForUpdate(id: Long): Admin

//typeorm
return getManager()
        .getRepository(Admin)
        .createQueryBuilder("admin")
        .setLock('pessimistic_write')
        .where("admin.id = :id", {id: id})
        .getOne();