트랜잭션

JIWOO YUN·2024년 4월 9일
0

SpringDB

목록 보기
5/11
post-custom-banner

트랜잭션

  • 하나의 거래를 안전하게 처리하도록 보장해주는 것
  • 데이터베이스의 상태를 변화시키기 위해서 수행하는 작업의 단위

트랜잭션 속성 - ACID

Atomicity(원자성) : 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공하거나 모두 실패해야한다.
Consistency(일관성) : 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야함.
Isolation(격리성) : 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 동시에 같은 데이터를 수정하지 못하게 해야함
  • 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준을 선택할 수 있음.

  • 트랜잭션의 격리 수준
    • READ UNCOMMITED(커밋되지 않은 읽기)
    • READ COMMITTED(커밋된 읽기)
    • REPEATABEL READ(반복 가능한 읽기)
    • SERIALIZABLE(직렬화 가능)
Durability(지속성) : 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되야한다. 중간에 시스템에 문제가 발생해도 데이터베이스 로그 등을 사용하여 성공한 트랜잭션 내요을 복구해야함.

트랜잭션의 격리수준( JPA 책 설명)
  • READ UNCOMMITED
    • 커밋 하지 않은 데이터를 읽을 수있다.
    • 트랙잭션1이 데이터를 수정하고 있는데 커밋하지 않아도 트랜잭션2가 수정 중인 데이터를 조회할 수있음. --> Dirty READ
    • 트랜잭션 2가 DirtyRead한 데이터를 사용하는데 트랜잭션 1을 롤백하면 데이터 정합성의 심각한 문제가 발생 할 수 있다.
  • READ COMMITTED
    • 커밋된 데이터만 읽을 수 있음

    • NON-REPEATABLE READ 가 발생할 수있다.

      • 트랜잭션 1이 회원 A 를 조회중에 갑자기 트랜잭션 2가 회원 A를 수정하고 커밋하면 트랜잭션 1이 다시 회원 A 를 조회 했을때 수정된 데이터가 조회되는 것.
  • REPEATABEL READ
    • 한번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회

    • PHANTOM READ 발생 가능

      • 반복 조회시 결과 집합이 달라지는 것을 의미
      트랜잭션1 이 10살이하로 회원을 조회했을때, 트랜잭션 2가 5살의 회원을 추가하고 커밋하고 트랙잭션1이 다시 10살이하의 회원을 조회시 회원하나가 추가된 상태로 조회되는 경우
    • NON-REPEATABLE READ 허용하지 않음

  • SERIALIZABLE
    • 가장 엄격한 트랜잭션 격리 수준

      • 동시성 처리 성능이 급격히 떨어질 수 있다.
    • PANTOM READ 발생안함

정합성 : 데이터의 올바른 유무와 상관없이 데이터들의 값이 서로 일치하는 상태


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

  1. 사용자는 WAS 나 DB 접근 툴 같은 클라이언트를 사용해서 DB 서버에 접근
  2. 클라이언트는 데이터베이스 서버에 연결을 요청하여 커넥션을 맺음
  3. 이 상황에 데이터베이스 서버는 내부에 세션을 생성
    1. 해당 커넥션을 통한 모든 요청은 현재 커넥션에 연결된 세선을 통해서 실행
  4. 세션은 트랜잭션을 시작하고 커밋 또는 롤백을 통해 트랜잭션을 종료
  5. 그리고 이후에 새로운 트랜잭션을 다시 시작할 수 있음.
  6. 사용자가 커넥션을 닫거나 또는 DBA가 세션을 강제로 종료시 세션은 종료된다.

커넥션 풀이 10개의 커넥션을 생성시, 10개의 세션이 만들어진다.

트랜잭션 사용법

  • 데이터 변경 쿼리 실행 후 데이터베이스에 결과를 반영하려면 commit 호출, 결과 반영을 하고 싶지 않은 경우 rollback 호출
  • 커밋을 호출하기 전까지 임시로 데이터를 저장
    • 해당 트랜잭션을 시작한 세션에게만 변경데이터가 보이고 다른 세션은 변경데이터가 보이지 않음
  • 등록, 수정, 삭제 모두 같은 원리로 동작한다.

커밋하지 않은 데이터를 다른곳에서 조회할 수 있으면 발생하는 문제

  • 데이터 정합성에 큰 문제가 발생
    • 커밋하지 않은 데이터가 보일시 다른 세션에서 조회시에 커밋되지 않은 데이터도 보이게 되고, 만약 이 데이터를 넣던 세션을 롤백을 수행하게되면 커밋되지 않은 데이터가 사라지게 되어 데이터가 일치하지 않게 되는 문제가 발생.

DB 예제 - 자동 커밋 , 수동 커밋

예제 스키마

drop table member if exists;
create table member (
	member_id varchar(10),
    money integer not null default 0,
    primary key (member_id)
)

자동 커밋

  • 자동 커밋 설정시 각각의 쿼리 실행 직후에 자동으로 커밋 호출
    • 커밋이나 롤백을 직접 호출하지 않아도 되는 편리함 존재
    • 단, 쿼리를 하나하나 실행할 때 마다 자동으로 커밋되기 때문에 우리가 원하는 트랜잭션 기능을 제대로 사용할 수 없다.
set autocommit true;
insert into member(member_id, money) values('data1',10000); /* 자동 커밋됨. */ 
insert into member(member_id, money) values('data2',20000); /* 자동 커밋됨. */ 
  • commit, rollback을 직접 호출하면서 트랜잭션 기능을 제대로 수행하려면 자동 커밋 설정을 끄고 수동커밋 상태로 사용해야함.

수동 커밋 설정

  • 자동커밋을 꺼주면 된다.
set autocommit false;
insert into member(member_id, money) values('data1',10000); 
insert into member(member_id, money) values('data2',20000); 
commit; /* 수동으로 커밋 해주기*/

보통의 경우 자동 커밋 모드가 기본으로 설정된 경우가 많기 때문에 수동 커밋 모드로 설정하는 것을 트랜잭션을 시작한다고 표현

  • 수동 커밋 설정을 할 경우 이후에 꼭 commit ,rollback 을 호출해야함.

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

트랜잭션 실습 해보기

  • 일단 h2 웹 콘솔창을 2개 켜준다
    • 여기서 중요한 점은 현재 jsessionid값이 달라야함
      • 둘의 sessionId가 같다면 같은 세션에 접근하기 때문에

자동 커밋 모드를 사용해서 별도로 커밋을 호출하지 않고 데이터를 초기화를 진행해주자.

set autocommit true;
delete from member;
insert into member(member_id, money) values('oldId',10000);
  • 자동 커밋이 활성화 되있기 때문에 commit을 직접적으로 호출하지 않아도 자동으로 커밋이되서 다른세션에서도 보이게됨.

수동 커밋 활성화 후 데이터 추가

set autocommit false; //수동 커밋 모드
insert into member(member_id, money) values ('newId1',10000);
insert into member(member_id, money) values ('newId2',10000);
  • 수동 커밋이기 때문에 커밋을 호출하기전까지 임시데이터로 해당 데이터를 추가한 세션에 추가만 되있고 다른 세션에서는 모르는 상태로 유지됨.
코드 실행후 세션1과 세션2의 데이터 차이

  • 세션1에는 임시데이터로 저장되어있어서 실제로는 데이터가 적용되지 않은 것을 확인할 수 있다.
세션1에서 commit을 하면 데이터가 저장이 되어 볼 수 있게 된다.

  • 임시데이터 상태에서 commit을 하지 않고 rollback을 진행하면 데이터가 추가되지않음.
profile
열심히하자
post-custom-banner

0개의 댓글