[Spring DB] 트랜잭션

easyone·2024년 9월 10일

Spring

목록 보기
2/18

트랜잭션

개념

  • 데이터베이스가 제공하는 트랜잭션은 두 작업이 모두 성공해야 저장하고, 중간에 하나라도 실패 시 전의 상태로 돌아가게 됨
  • 모두 성공 시 Commit을 통해 정상 반영되고, 실패해서 이전으로 RollBack을 통해 되돌릴 수 있음

트랜잭션 ACID

  • 원자성 : 트랜잭션 내에서 실행한 작업은 모두 성공하거나 모두 실패해야함
  • 일관성 : 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야함
  • 지속성 : 트랜잭션을 성공적으로 끝낼 시 결과가 항상 기록되어야 하고 중간에 문제 발생 시 로그 등을 사용하여 성공한 트랜잭션을 복구 가능해야 함
  • 격리성 : 동시에 실행되는 트랜잭션이 서로에게 영향을 미치지 않도록 격리해야 함, 트랜잭션 격리 수준을 선택할 수 있음
    -> 격리성을 완벽하게 보장하려면 트랜잭션을 순서대로 실행해야 하는데, 병렬처리가 안되므로 동시 처리 성능이 나빠지므로 격리 수준을 설정해야 함

트랜잭션 격리 수준

  • READ UNCOMMITED: 커밋되지 않은 읽기- 데이터를 변경 중이고 커밋하지 않은 상태에서 데이터 읽기가 가능하므로 문제가 발생할 수 있음
  • READ COMMITED: 커밋된 읽기
  • REPEATABLE READ: 반복 가능한 읽기
  • SERIALZABLE: 직렬화 가능

DB 세션

  • 커넥션 생성 시 데이터베이스 서버는 내부에 세션을 만들고 모든 요청이 세션을 통해 실행됨
  • 사용자가 커넥션을 닫거나 관리자가 세션 강제 종료 시 종료됨

트랜잭션 동작

  • 쿼리 실행하고 데이터베이스에 결과 반영하려면 commit, 결과 반영하고 싶지 않을 경우 rollback 호출
  • 커밋 호출하기 전까지는 임시로 데이터를 저장하고 다른 세션 사용자에게는 해당 데이터가 보이지 않음
  • 커밋하지 않은 데이터를 다른 세션에서 조회 가능할 경우, Rollback을 수행하면 커밋하지 않은 상태에서 변경한 데이터가 사라지기 때문에 데이터 정합성에 문제 발생
  • 세션1에서 신규 데이터를 추가한 후에 commit을 호출하면 세션2에서도 조회 가능
  • 세션1에서 데이터 추가 후 rollback 호출 시 트랜잭션 시작하기 직전의 상태로 복구됨

자동 커밋과 수동 커밋

  • 자동 커밋: 각각의 쿼리를 실행할 때마다 실행 직후에 자동으로 커밋 호출 -> 커밋,롤백을 직접 호출하지 않아도 되지만 트랜잭션 기능을 사용하기 어려움
  • 자동 커밋이 기본적으로 설정되어 있는데 수동 커밋 모드로 설정해야함
  • 수동 커밋 설정 시 이후에 꼭 commit, rollback을 호출해야 함
  • 한번 커밋 모드를 설정 시 해당 세션에서 계속 유지되며 중간에 변경 가능
  • 수동 커밋으로 변경 시 트랜잭션이 시작된다고 할 수 있음

계좌이체 예제

데이터 : memberA -10000원, memberB - 10000원

  • 상황1: 계좌이체 정상
    - 세션1에서 멤버A의 돈을 멤버B에게 2000원 계좌이체하는 트랜잭션을 실행하면 자동으로 커밋되기 때문에 계좌이체가 정상적으로 진행됨
  • 상황2: 계좌이체 문제 상황 - 커밋
    - 계좌이체 진행하는 도중에 멤버A의 돈이 빠져나가는 것만 적용되고 멤버B에게 이체되는 쿼리는 오류가 발생해서 반영이 안되는 상태에서 자동으로 커밋됨 -> 계좌이체가 실패했지만 A의 돈이 빠져나가는 것만 적용됨
  • 상황3: 계좌이체 문제 상황 - 롤백
    - 롤백을 호출해서 계좌이체 실행 전으로 돌아와야함

DB 락

개념

  • 동시에 데이터를 수정할 때 발생하는 문제를 해결
  • 데이터를 변경하려고 할 때 해당 로우의 락을 획득해야함 -> 다른 세션에서 데이터를 변경하고자 하는데 락이 없으면 락이 돌아올 때까지 대기해야 하며, 대기 시간을 넘어가면 타임아웃 오류 발생
  • 락이 있는 세션에서 트랜잭션 종료 시에 락을 반납하게 되며, 다른 세션에서 락을 획득할 수 있게 됨
  • SET LOCK_TIMEOUT <milliseconds> : 락 획득 시간을 설정 하고 시간 안에 락을 얻지 못하면 예외 발생

락 조회

  • 일반적 조회에서는 락을 사용하지 않음 -> 세션1에서 락 획득하고 변경하고 있어도 세션2에서 조회 가능
  • select for update : 데이터 조회할 때 락을 획득하고 싶을 때 사용
  • 조회 시점에 락이 필요한 경우: 트랜잭션 종료 시점까지 해당 데이터가 변경되면 안될 때 사용
profile
백엔드 개발자 지망 대학생

0개의 댓글