minghxx.blog
  • [Spring] 스프링 DB 1편 3) 트랜잭션 이해(1)
    2023년 11월 13일 09시 42분 37초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

    스프링 DB 1편 데이터 접근 핵심 원리

    Session 3 트랜잭션 이해

    1. 트랜잭션 개념이해

    1) 트랜잭션

    데이터베이스를 사용하는 이유는 트랜잭션이라는 개념을 지원하기 때문

    데이터베이스에서 트랜잭션은 하나의 거래를 안전하게 처리하도록 보장해 주는 것

    모든 작업이 성공해서 데이터베이스에 정상 반영하는 것을 커밋이라고 하고 작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것을 롤백이라고 한다.

     

    2) 트랜잭션 ACID

    원자성 Atomicity : 트랜잭션 내에서 실행한 작업은 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야 한다.

    일관성 Consistency : 트랜잭션은 일관성 있는 데이터베이스 상태 유지해야 한다. 

    격리성 Isolation : 동시에 실행되는 트랜잭션이 서로에게 영향을 미치지 않도록 격리해야 한다. 격리성은 동시성과 관련된 성능 이슈로 트랜잭션 격리 수준을 선택할 수 있다.

    지속성 Durability : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 문제가 발생해도 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 한다.

     

    3) 트랜잭션 격리 수준 Isolation level 

    트랜잭션은 원자성, 일관성, 지속성을 보장한다. 격리성을 완벽히 보장하려면 트랜잭션을 거의 순서대로 실행해야 하기 때문에 동시처리 성능이 매우 나빠진다. 이런 문제로 ANSI 표준은 격리 수준을 4단계로 나눠 정의함

    - ANSI 표준은 격리 수준

    READ UNCOMMITED 커밋되지 않은 읽기

    READ COMMITED 커밋된 읽기

    REPEATABLE READ 반복 가능한 읽기

    SERIALIZABLE 직렬화 가능

    단계가 높아질수록 성능이 느려진다.

    일반적으로 많이 사용하는 READ COMMITED 격리 수준으로 강의 진행


    2. 데이터베이스 연결 구조와 DB 세션

    1) 데이터베이스 연결 구조와 DB 세션

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

    클라이언트는 데이터베이스 서버에 연결을 요청하고 커넥션을 맺음

    이때 데이터베이스 서버 내부에 세션을 생성하고 해당 커넥션을 통한 모든 요청은 세션을 통해 실행한다.

     커넥션 풀이 10개의 커넥션을 생성하면 세선도 10개 만들어짐

     개발자가 클라이언트를 통해 SQL을 전달하면 현재 커넥션에 연결된 세션이 SQL을 실행

    세션은 트랜잭션을 시작하고 커밋, 롤백을 통해 트랜잭션을 종료. 이후 새로운 트랜잭션을 다시 시작할 수 있다.

    사용자가 커넥션을 닫거나 DBA(DB 관리자)가 세션을 강제로 종료하면 세션은 종료된다.


    3. 트랜잭션 - DB 예제 개념이해

    참고! 트랜잭션 개념의 이해를 돕기 위한 예시로 구체적인 실제 구현 방식은 데이터베이스마다 다르다

    1) 트랜잭션 사용법

    데이터 변경 쿼리를 실행하고 결과를 반영하려면 commit을 호출하고 결과를 반영하고 싶지 않으면 rollback을 호출

    커밋을 호출하기 전까지는 임시로 데이터를 저장하고 있다 ▶ 해당 트랜잭션을 시작한 세션(사용자)에게만 변경 데이터가 보이고 다른 세션에서는 변경 데이터가 보이지 않는다

    2) 신규 데이터 추가

    세션 1은 트랜잭션을 시작 ▶ 신규 회원 1, 2를 추가, 커밋은 하지 않음

    세션 1은  신규회원 1, 2를 조회할 수 있지만 세션 2는 조회하지 못한다.

     

    3) 커밋하지 않은 데이터를 다른 곳에서 조회가능하면 생기는 문제점

    세션 1에서 추가한 회원 1, 2를 이용해 세션 2에서 로직을 수행할 때 세션 1에서 롤백을 수행하게 되면 신규회원 1, 2의 데이터는 없어지면서 데이터 정합성에 문제가 생긴다.

     

    4) 신규 데이터 추가 후 커밋

     

    세션 1이 데이터를 추가 후 commit을 호출

    새로운 데이터가 실제 데이터베이스에 반영되고 데이터의 상태도 임시에서 완료로 변경

    다른 세션에서도 신규 회원을 확인 가능

     

    5) 신규 데이터 추가 후 롤백

    세션 1이 데이터를 추가 후 rollback을 호출

    세션 1이 데이터베이스에 반영한 모든 데이터가 처음 상태로 복구

    트랜잭션을 시작하기 직전의 상태로 복구된다.


    4. 트랜잭션 - DB 예제 자동 커밋, 수동 커밋

    1) 자동 커밋

    각각 쿼리 실행 직후에 자동으로 커밋을 호출, 커밋이나 롤백을 직접 호출할 필요가 없지만 쿼리를 하나 실행할 때마다 자동으로 커밋되어 버리기 때문에 원하는 대로 트랜잭션 기능을 제대로 사용할 수 없다.

    set autocommit true;//자동 커밋 모드 설정 
    insert into member(member_id,money) values('data1',10000);//자동 커밋 
    insert into member(member_id,money) values('data2',10000);//자동 커밋

     

    2) 수동 커밋

    commit과 rollback을 직접 호출하면서 트랜잭션 기능을 제대로 수행하려면 자동 커밋을 끄고 수동커밋을 이용

    수동 커밋 설정하면 꼭 commit과 rollback을 호출

    만약 호출을 안 하면 타임아웃에 의해 자동 rollback 실행

    자동 커밋이나 수동커밋 모드는 한번 설정하면 해당 세션에서는 계속 유지

    set autocommit false;//수동 커밋 모드 설정
    insert into member(member_id, money) values ('data3',10000);
    insert into member(member_id, money) values ('data4',10000); 
    commit; // 수동커밋

     


     

    6. 트랜잭션 - DB 예제 계좌이체

    1) 계좌이체 실행 오류

    set autocommit false;
    update member set money=10000 - 2000 where member_id = 'memberA'; //성공 
    update member set money=10000 + 2000 where member_iddd = 'memberB';//쿼리 예외 발생

     

    계좌이체를 실행하는 도중 SQL에 문제 발생

    ▶ memberA의 돈은 2000원 줄었지만 memberB의 돈은 2000원 증가하지 않았음

    이때 commit을 실행하게 되면 memberA의 돈만 2000원 줄어드는 심각한 문제 발생

     

    2) 계좌이체 실행 오류 롤백

    롤백을 통해 트랜잭션을 시작하기 전 단계로 데이터 복구

    728x90
    댓글