오늘 뭐했냐/개발에 대한 주저리

23.07.23 트랜젝션 (Transaction)

스스로에게 2023. 7. 24. 19:26

트랜잭션이란, 데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위

 

특징

  • 첫 번째로, 원자성은 트랜잭션이 데이터베이스에 모두 반영되던가, 아니면 전혀 반영되지 않아야 한다는 것
  • 두 번째로, 일관성은 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것
  • 세 번째로, 독립성은 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도, 다른 트랜잭션의 연산에 끼어들 수 없다는 점을 가리킨다.
  • 네 번째로, 지속성은 트랜잭션이 성공적으로 완료됐을 경우, 결과는 영구적으로 반영되어야 한다는 점

 

Isolation Level과 Lock

Isolation level이 선택되면 해당 격리 수준에 따라 필요한 lock 동작과 전략이 결정. 다시 말해, Isolation level은 데이터의 일관성과 동시성 간의 균형을 어떻게 유지할 것인지를 결정하는 기준이며, 이를 실제로 구현하기 위해 데이터베이스는 다양한 락 전략을 사용한다.

 

Isolation Level에 따라 아래와 같은 현상들이 발생할 수 있다.

  1. Dirty Read: 하나의 트랜잭션이 수정 중인 데이터를 다른 트랜잭션이 읽는 현상.
  2. Non-repeatable Read: 하나의 트랜잭션 도중에 다른 트랜잭션이 값 변경을 수행하여 동일 트랜잭션 내에서 같은 데이터를 여러 번 조회할 때 값이 다르게 보이는 현상.
  3. Phantom Read: 한 트랜잭션 도중에 다른 트랜잭션에서 새로운 레코드 추가나 삭제를 통해 원래의 쿼리 결과와 다르게 나오는 현상.

Isolation Level은 데이터베이스 트랜잭션에서 동시에 여러 트랜잭션이 수행될 때, 어느 정도의 격리 수준을 가질지 결정. 이를 통해 트랜잭션의 동시성과 데이터의 일관성 간의 균형을 맞춘다.

  1. Read Uncommitted:가장 낮은 격리 수준. 다른 트랜잭션이 아직 커밋되지 않은 데이터를 읽을 수 있음. Dirty read가 발생할 수 있음. (Dirty Read 위험) 
  2. Read Committed: 대부분의 RDBMS의 기본 값. 다른 트랜잭션에 의해 변경되고 아직 커밋되지 않은 데이터는 읽지 않음. (Non-repeatable Read 위험)
  3. Repeatable Read: 같은 트랜잭션 내에서 데이터를 여러 번 읽을 때 일관된 값을 보장. (Phantom Read 위험)
  4. Serializable: 가장 높은 격리 수준. 모든 현상을 방지. 하지만 동시성이 가장 낮아 성능에 영향을 줄 수 있음.

Lock은 데이터를 보호하기 위한 메커니즘. 데이터의 일관성과 무결성을 유지하기 위해 동시에 여러 트랜잭션에서 동일한 데이터에 접근하는 것을 제한한다.

  1. Shared Lock (S-Lock): 데이터를 읽기 위한 락. 다른 트랜잭션도 동일한 데이터에 대한 S-Lock을 얻을 수 있지만, Exclusive Lock은 획득할 수 없음.
  2. Exclusive Lock (X-Lock): 데이터 수정을 위한 락. 한 트랜잭션이 X-Lock을 보유하고 있으면 다른 트랜잭션은 해당 데이터에 대한 어떠한 락도 얻을 수 없음.
  3. Intent Lock: 특정 레벨의 락을 얻기 위한 의도를 나타내는 락. 예를 들어, 특정 row에 X-Lock을 얻기 원하면 그 row가 속한 페이지나 테이블에 Intent Lock을 먼저 설정합니다.
  4. Update Lock (U-Lock): 데이터를 업데이트할 예정이라는 것을 나타내는 락. 이후 X-Lock으로 업그레이드될 수 있음.

 

요약하면, 선택된 Isolation level에 따라 필요한 락 전략이 결정된다.

 

왜 트랜젝션을 사용할까 하면 아주 쉽게 이해할 수 있는 게 돈 문제이다. 우리가 돈을 보낸다면 내 계좌에서 돈이 빠져나가고 내가 보낸 돈을 누군가가 받을 것이다. 그런데 이 과정에서 만약에 내 계좌에서 돈만 빠지고 상대방이 받지  못한다면 문제가 될 것이고, 내가 빠진 돈을 다시 채워서 기존 상태로 돌려야 한다. 그래서 이런 과정들을 작업의 단위로 하는 것이 트랜잭션이며 사용해야 할 이유이다.