https://www.youtube.com/watch?v=sLJ8ypeHGlM

https://easy-code-yo.tistory.com/26

 

트랜잭션 영상들 전체 흐름 파악하기

* 이 글은 쉬운코드에 올린 트랜잭션 영상들이 개념적으로 어떻게 연결되는지 전체 그림을 설명하기 위한 목적으로 작성했습니다 * 위에서 아래 순서로 영상을 보는 것을 추천합니다 Transaction &

easy-code-yo.tistory.com

영상에서 다루는 내용

database transaction

ACID

에 대해서 정리하고있다.

 

J가 H에게 20만원을 이체한다고한다. 각자의 계좌는 어떻게 변경될까?

J는 계좌에 100만원이 잇다. H는 200만원이 잇다.

J계좌에서 20만원을 뺸다. 80만원이 된다.

H의 계좌에 20만원을 넣어준다. 220만원이 된다.

 

위의 과정을 SQL로 표현해보자.

UPDATE account SET balance = balance -200000 WHERE id = 'J';

UPDATE account SET balance = balance + 200000 WHERE id = 'H'

이 2개의 SQL이 '반드시' 같이 실행되고 성공해야한다.

 

둘다 정상처리돼야만 성공하는 단일작업이다.

두개의 SQL구문이 모두 성공해야만 하는 작업을 TRANSACTION 이라 한다.

 

Transaction이란?

단일한 논리적인 작업 단위(a single logical unit of work)

논리적인 이유로 여러 SQL문들을 단일 작업으로 묶어서 나눠질 수 없게 만든것이 transaction 이다.

transaction의 SQL 문들 중에 일부만 성공해서 DB에 반영되는 일은 일어나지 않는다.

 

 

이체예제를 MYSQL에서 transaction 을 활용해서 구현한다.

select * from account;

J가 H에게 20만원을 이체하는것을 transaction 으로 구현한다.

START TRANSACTION;

UPDATE account SET balance = balance - 20000 where ID = 'J';
UPDATE account SET balance = balance + 20000 where ID = 'H';

COMMIT;

Commit을 통해 지금까지 작업한 내용을 DB에 영구적으로 저장하라. transaction을 종료한다.

 

select * from account;

 

이제 J계좌에서 80만원이 되고 , H계좌는 220만원이 된다.

 

J가 H에게 30만원 이체하는것을 transaction으로 구현해본다.

START TRANSACTION;

UPDATE account SET balance = balance - 30000 where ID = 'J';

SELECT * from account; //transaction 중에 확인한다. 30000 원이 빠져있다는것을 확인가능하다.
ROLLBACK // 지금까지 작업 모두 취소하고, transaction 이전상태로 되돌린뒤 trnasaction을 종료한다.
SELECT * FROM account //다시 원래대로 돌아왔다.
UPDATE account SET balance = balance + 30000 where ID = 'H';

COMMIT;

 

AUTOCOMMIT이란.

SELECT @@AUTOCOMMIT; //현재 autocommit이 활성화되어있는지 확인한다. 활성화되어있다면 1(true).
  • 각각의 SQL문을 자동으로 transaction 처리해주는 개념
  • SQL문이 성공적으로 실행하면 자동으로 commit 한다.
  • 실행중에 문제가 있었다면 알아서 rollback한다.
  • MYSQL에서는 default로 autocommit이 enabled되어잇다.
  • 다른 DBMS에서도 대부분 다른 기능을 제공한다.
insert into account values ('W', 10000000);
  • autocommit이 enabled된 상태이기에 insert문을 실행하면 자동으로 commit이 되면서 account테이블에 ('W', 100000)데이터가 영구적으로 저장된다.
select * from account; //아이디가 W인 것이 삽입되다.

 

 

만약 autocommit이 비활성화상태라면?

SET autocommit = 0; //autocommit 비활성화

DELETE FROM account WHERE balance <= 1000000;
Query OK. 2rows affected.

SELECT * from account;
이제 H 계좌만 남겼다.

현재 상황은 autocommit은 0 인상황이다. 
이 상태에서 롤백을 한다면, 이전 상태로 돌아갈 수 있다.
삭제했던 듀개의 계좌를 다시 살릴 수 있다.

ROLLBACK

select * from account;
//다시 복구가 되어있다.

 

 

START TRANSACTION:

UPDATE account SET balance = balance - 200000 WHERE id = 'J';

UPDATE account SET balance = balance + 200000 WHERE id = 'H';

COMMIT;

STARRT Transaction 실행과 동시에 autocommit은 off된다.
COMMIT / ROLLBACK 과 함꼐 Transaction이 종료되면 원래 autocommit 상태로 돌아간다.

 

 

일반적인 transaction 사용 패턴

1. transaction 을 시작(begin)한다.

2. 데이터를 읽거나 쓰는 등의 SQL 문들을 포함해서 로직을 수행한다.

3. 일련의 과정들이 문제 없이 동작했다면, transaction을 commit 한다.

4. 중간에 문제가 발생했다면 transaction을 rollback한다.

 

 

 

실제로 개발을할때 이렇게 SQL문들을 직접 DB서버에 붙여서 사용하지 않는다.

프로그래밍 언어를 통해 START TRANSACTION, COMMIT을 프로그래밍언어로 대체한다.

JAVA 예시이다.

public void transfer(String fromId, String told, int amount){
	try{
    	Connection connection = ...; //get DB connection ..
        connection.setAutoCommit(false); //means START TRANSACTION , autocommit을 false로 만든다. 이를 통해 transaction을 활용가능하다.
        ...				//update at fromId
        ...				// update at told
        connection.commit();
    } catch(Exception e){
    	...
        connection.rollback(); //예외발생시 롤백한다.
        ...
    } finally{
    	connection.setAutoCommit(true); //다시 autocommit을 true로 만들어준다. 이 connection은 버려지는것이 아닌 재활용되기에 원래 설정으로 돌아온다. 
    }
}

 

만약 Trnasactional 어노테이션을 붙인다면, 

@Transactional
public void transfer(String fromId, String told, int amount){
	//로직만 남는다.
    //위의 autocommit(false), rollback, 이런작업들이 어노테이션으로 대체된다.
}

 

 

Transaction의 핵심 ACID란? 

각 개념들은 Transaction이 가져야할 개념들을 의미한다.

- Atomicity

- Consistency

- Isolation

- Durability

 

Atomicity

아까 살펴보면 20만원을 이체하는 예제이다.

아까 앞에서 설명한것처럼 일부만 성공해서는 안된다. 둘다 성공해야만 의미가 있는 작업이다.

모두 성공하거나, 모두 실패해야하는 작업이다.

이런 특징을 Atomicity(원자성)을 의미한다. 

  • All or Nothing
  • transaction은 논리적으로 쪼개질 수 없는 작업 단위이기 때문에 내부의 SQL 문들이 모두 성공해야한다.
  • 중간에 SQL문이 실패하면 지금까지의 작업을 모두 취소하여 아무일도 없었던 것처럼 rollback 한다.
  • commit 실행시 DB에 영구적으로 저장하는 것은 DBMS가 담당하는 부분이다.
  • rollback 실행시 이전 상태로 되돌리는것도 DBMS가 담당하는 부분이다.
  • 개발자는 언제 commit하거나 rollback 할지를 챙겨야한다.

 

Consistency

J : 80만원. H: 220만원이 있다.

J가 H에게 100만원을 추가로 이체한다고 해보자.

J의 계좌에서 100만원을 빼면 -20 만원이 된다. H의 계좌는 320 만원이 된다.

문제는 처음 account table을 만들떄

CREATE TABLE account (
	...,
    balance INT,
    check (balance >= 0)
)

양수여야만한다. 0 보다 커야하는 Straint가 존재한다.

 

해당 update문은 일관성을 꺠드리기 때문에, constraint로 인해 INCONSISTENT가 발새안다. 즉 ROLLBACK을 해줘야한다. 데이터베이스의 일관성을 유지시켜주는것이 Consistency 다.

 

  • transaction은 DB 상태를 consistent 상태에서 또 다른 consistent 상태로 바꿔줘야한다.
  • constraints, trigger 등을 통해 DB에 정의된 rules을 transaction이 위반했다면 rollback 해야한다.
  • transaction이 DB에 정의된 rule을 위반했는지는 DBMS가 commit 전에 확인하고 알려준다.
  • 그 외에 application 관점에서 transaction이 consistent 하게 동작하는지는 개발자가 챙겨야한다.

 

Isolation(격리, 분리)

J가 H에게 20만원을 이체할때, H도 ATM에서 본인계좌에 30만원을 입금한다면,

transactionb이 isolation 되지 않는다면 올바르게 작동하지 않는다.

J의 계좌에 얼마가 있는지 잔액을 조회한다.
read (balance) = > 100만원이 잇다.
write ( balance = 80 만원 ) 

read(balance) => 200 만원.
    { transction 2
		30만원을 입금.
        read(balance) = 200
        write(balance = 230)
    }
write(balance = 220 ) + 20
  • 여러 transaction들이 동시에 실행될때도 혼자 실행되는 것처럼 동작하게 만든다.
    • 엄격하게 구현시 DB Server의 Performance가 감소한다.
  • DBMS는 여러 종류의 isolation level을 제공한다.
    • 성능을 위해 여러 종류를 제공한다. 레벨이 높으면 높을수록 보다 엄격하여 다른 트랜잭션으로부터 영향을 받을 경우가 줄어든다.
    • 대신에 그만큼 엄격하게 격리를 시키니 동시에 실행될 수 있는 동시성(COncurrnecy)가 떨어져 퍼포먼스가 떨어진다.
  • 개발자는 isolation level 중에 어떤 level로 transaction을 동작시킬지 설정할 수 있다.
  • concurrency control의 주된 목표가 isolation 이다.

 

Durability(영존성)

J가 H에게 20만원을 이체하는 예시를 생각해보자.

commit된 이 transaction은 DB에 영구적으로 저장된다. 이것이 Durability 이다.

  • commit된 transaction은 DB에 영구적으로 저장된다.
  • 즉, DB System에 문제(Power fail or DB crash)가 생겨도 commit 된 transaction 은 DB에 남아있는다.
  • '영구적으로 저장한다' 라고 할때는 일반적으로 비휘발성 메모리(HDD, SSD, ..)에 저장함을 의미한다.
  • 기본적으로 transaction의 durability는 DBMS가 보장한다.

 

참고사항

  • 1. transaction을 어떻게 정의해서 쓸지는 개발자가 정한다.
    • 구현하려는 기능과 ACID 속성을 사용한다.
  • 2. transaction의 ACID 와 관련해서 개발자가 챙겨야하는 부분들이 있다.
    • DBMS가 모든것을 알아서 해주는것이 아니다.
  • 3. 위의 transaction SQL 예제는 MYSQL이다. 각 RDBMS마다 문법이 조금 다를 수 있다.

+ Recent posts