엄지월드

트랜잭션 본문

Server&DevOps/Database

트랜잭션

킨글 2024. 4. 14. 21:20
반응형

트랜잭션 격리수준

- READ UNCOMMITED(커밋되지 않은 읽기) -> 성능 면에서 유리하긴 하다.

- READ COMMITTED(커밋된 읽기)

- REPEATABLE READ(반복 가능한 읽기)

- SERIALIZABLE(직렬화 기능)

 

사용자는 웹 애플리케이션 서버(WAS)나 DB 접근 툴 같은 클라이언트를 사용해서 데이터베이스 서버에 접근할 수 있다.

클라이언트는 데이터베이스 서버에 연결을 요청하고 커넥션을 맺게 된다. 이때 데이터베이스 서버는 내부에 세션이라는 것을 만든다. 그리고 앞으로 해당 커넥션을 통한 모든 요청은 이 세션을 통해서 실행하게 된다. 

 

락 타임아웃

SET LOCK_TIMEOUT 10000 (10초), 세션2에 설정하면 세션2가 10초 동안 대기해도 락을 얻지 못하면 락 타임아웃 오류가 발생한다. 

 

조회와 락

  • 데이터를 조회할 때도 락을 획득하고 싶을 때가 있다. 이럴 때는 select for update 구문을 사용하면 된다.
  • 이렇게 하면 세션1이 조회 시점에 락을 가져가 버리기 때문에 다른 세션에서 해당 데이터를 변경할 수 없다.
    물론 이 경우도 트랜잭션을 커밋하면 락을 반납한다. 
  • set autocommit false; 
    select * from member where member_id = 'memberA' for update;
    ....
    ... 
    이 순간에 다른 세션에서 update를 해도 commit이 안되어서 대기한다. 
    단, select는 된다. 

 

조회 시점에 락이 필한 경우는 언제일까?

  • 트랜잭션 종료 시점까지 해당 데이터를 다른 곳에서 변경하지 못하도록 강제로 막아야 할 때 사용한다.
  • 예를 들어서 애플리케이션 로직에서 memberA의 금액을 조회한 다음에 이 금액 정보로 애플리케이션에서 어떤 계산을 수행한다.
    그런데 이 계산이 돈과 관련된 매우 중요한 계산이어서 계산을 완료할 때까지 memberA의 금액을 다른곳에서 변경하면 안된다. 이럴때 조회 시점에 락을 획득하면 된다.

 

테스트 

정상

실패(예외)

데이터 초기화

  • BeforeEach : 각각의 Test 수행 전에 실행된다.
  • AfterEach : 각각의 Test 수행 후에 실행된다. 

 

  • 애플리케이션에서 DB 트랜잭션을 사용하려면 트랜잭션을 사용하는 동안 같은 커넥션을 유지해야 한다.
    그래야 같은 세션을 사용할 수 있다. 
Comments