본문 바로가기
Spring Study/DataBase

[DataBase] 트랜잭션 (Transaction)

by 정재인 2023. 9. 18.

트랜잭션 (Transaction)이란?

데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위를 뜻한다.

커밋(Commit): 모든 작업이 성공해서 데이터베이스에 정상 반영하는 것
롤백(Rollback): 작업 중 하나라도 실패해서 거래 이전으로 되돌리는 것

 

트랜잭션 ACID

원자성(Atomicity)

트랜잭션 내에서 실행한 작업들은 하나의 작업인 것 처럼 모두 성공하거나 모두 실패

일관성(Consistency)

모든 트랜잭션은 일관성 있는 데이터베이스 상태 유지, 무결성 제약 조건을 항상 만족

격리성(Isolation)

동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리, 동시에 같은 데이터 수정 X

지속성(Durability)

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

 

트랜잭션 격리 수전 - Isolation level

- READ UNCOMMITED(커밋되지 않은 읽기)

- READ COMMITED(커밋된 읽기)

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

- SERIALIZABLE(직렬화 가능)

 


트랜잭션 - 개념 이해

트랜잭션 사용법

데이터 변경 쿼리를 실행하고 데이터베이스에 그 결과를 반영하려면 commit을 호출하고, 결과를 반영하고 싶지 않으면 rollback을 호출한다.

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

 

세션1, 세션2 모두 가운데 있는 기본 테이블을 조회하면 해당 데이터가 그대로 조회된다.

세션1은 트랜잭션을 시작하고 신규 회원1, 2를 DB에 추가했다. 하지만 커밋을 하지 않았기 때문에 새로운 데이터는 임시 상태로 저장된다.

따라서 세션1은 select 쿼리로 본인이 입력한 신규 회원1, 2를 조회할 수 있지만 세션2는 조회할 수 없다.

 

세션1이 신규 데이터를 추가한 후 commit을 호출하였으므로, 새로운 데이터가 실제 데이터베이스에 반영된다.

따라서 다른 세션에서도 신규 회원들을 조회할 수 있다.

 

세션1이 신규 데이터를 추가한 후 rollback을 호출했기 때문에 세션1이 데이터베이스에 반영한 모든 데이터가 처음 상태로 복구된다.

수정하거나 삭제한 데이터도 rollback을 호출하면 모두 트랜잭션을 시작하기 직전의 상태로 복구된다.

 


트랜잭션 - 자동 커밋, 수동커밋

자동 커밋

자동 커밋은 쿼리 실행 직후 자동으로 커밋을 호출한다. 따라서 커밋이나 롤백을 직접 호출하지 않아도 되는 편리함이 있다. 하지만 쿼리를 자동으로 커밋하게 되면 원하는 트랜잭션 기능을 제대로 사용할 수 없다.

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

 

수동 커밋

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

수동 커밋 설정을 하면 이후 꼭 commit, rollback을 호출해야 한다.

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

 


DB 락 - 개념

세션1이 트랜잭션을 시작하고 데이터를 수정하는 동안 커밋을 수행하지 않았는데, 세션2에서 동시에 같은 데이터를 수정하게 되면 문제가 발생하는데 이것이 바로 원자성이 깨지는 것이다.

이런 문제를 방지하려면 세션이 트랜잭션을 시작하고 데이터를 수정하는 동안에는 커밋이나 롤백 전까지 다른 세션에서 해당 데이터를 수정할 수 없게 막아야 한다.

 

세션1은 memberA의 금액을 500원으로, 세션2는 memberA의 금액을 1000원으로 변경하려고 한다.

1. 세션1이 트랜잭션을 시작한다.

2. 세션1은 memberA의 money를 500으로 변경한다. 이때 해당 로우의 락을 먼저 획득해야 한다.

3. 세션1은 락을 획득했으므로 해당 로우에 update sql을 수행한다.

4. 세션2는 트랜잭션을 시작한다.

5. 세션2도 memberA의 money 데이터를 변경하려고 한다. 이때 해당 로우의 락을 먼저 획득해야 한다. 락이 없으므로 락이 돌아올 때까지 대기한다.

6. 세션1은 커밋을 수행 후, 커밋으로 트랜잭션이 종료되었으므로 락도 반납한다.

세션2가 락을 획득한다.

7. 세션2는 update sql을 수행한다.

8. 세션2는 커밋을 수행하고 트랜잭션이 종료되었으므로 락을 반납한다.

 

 

'Spring Study > DataBase' 카테고리의 다른 글

[DataBase] 예외 처리  (0) 2023.09.21
[DataBase] 자바 예외 (Exception)  (0) 2023.09.20
[DataBase] 트랜잭션 (Transaction)2  (0) 2023.09.19
[DataBase] Connection Pool / DataSource  (2) 2023.09.14
[DataBase] JDBC란?  (0) 2023.09.13

댓글