Lock 기법에서는 read/read lock 끼리만 block을 하지 않아, 이 때만 서로 다른 트랜잭션이 동시에 특정 데이터접근이 가능했다.
그러나 트랜잭션 처리량이 적어 성능적인 이슈가 있었고
이를 해결하고자 MVCC가 등장하였다.
Keyword
MVCC, Locking read
아래 상황을 살펴보자.
그럼 tx1의 두번째 read는 어떤 값을 읽어올까?
Isolation level에 따라 다르다.
MVCC를 사용할 때도 Lost-update, write-skew와 같은 이상현상이 발생한다.
postgreSQL과 MySQL의 해결방식이 조금은 다른데 알아보도록 하자.
PostgreSQL에서는 read committed level에서 Lost-update가 발생한다.
PostgreSQL는 Update에 참여하는 모든 트랜잭션이 repeatable read를 사용할 경우,
Lost-update문제를 해결할 수 있다.
postgreSQL에서는 repeatable read level에서
같은 데이터에 먼저 update한 tx가 commit 되면 나중 tx는 rollback 된다.(first-updater-win)
mysql에서는 lost update를 방지하기 위해서는 repeatable read만 가지고는 해결되지 않는다.
Locking read를 함께 사용해야 한다.
Locking read
- read를 하면서도 read lock과 함께 write lock도 함께 획득하게 되는 것.
- sql 쿼리문에 FOR UPDATE를 붙여줌으로 써 Locking read가 적용된다.(exclusive lock 획득)
- FOR SHARE를 붙여줄 수도 있다.(shared lock 획득)
- Locking read는 가장 최근의 commit된 데이터를 읽는다.
isolation level과는 무관.SELECT balance FROM account WHERE id='x' FOR UPDATE or (FOR SHARE)
Repeatable Read 격리 수준에서 write skew를 피하기 위해서는
MySQL, PostgreSQL Locking Read를 사용해야 한다.
Reference
쉬운코드 - MVCC 1,2 편