우리가 데이터를 파일이 아닌 데이터베이스에 저장하는 이유는
데이터베이스는 트랜잭션이라는 개념을 지원한다.
트랜잭션은 데이터베이스 안에서 하나의 거래를 안전하게 처리하도록 보장해주는 것을 뜻한다.
예를 들어 A가 B에게 5000원을 계좌이체 하는 상황에서
1. A의 잔고 5000원 감소
2. B의 잔고 5000원 증가
이 두가지 작업이 하나의 작업처럼 진행되어야 한다.
트랜잭션이 없다면 1이 성공했을때 2는 실패하거나
2가 성공했을 때 1이 실패하면 큰 문제를 야기할 수 있다
트랜잭션 기능을 사용하면 둘 다 성공해야 결과를 저장(Commit)하고
하나라도 실패하면 그 전의 상황으로 롤백(Rollback)한다.
트랜잭션은 ACID를 보장해야한다.
- 원자성 (Atomicity) - 트랜잭션 내에서 실행한 작업들은 마치 하나의 작업인 것처럼 모두 성공 하거나 모두 실패해야 한다.
- 일관성 (Consistency) - 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다. 예를 들어 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다.
- 격리성 (Isolation) - 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다. 예를 들어 동시에 같은 데이터를 수정하지 못하도록 해야 한다. 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준 (Isolation level)을 선택할 수 있다.
- 지속성 (Durability) - 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다. 중간에 시스템에 문제가 발생해도 데이터베이스 로그 등을 사용해서 성공한 트랜잭션 내용을 복구해야 한다.
트랜잭션 격리 수준 (solation level)
- READ UNCOMMITED(커밋되지 않은 읽기)
- READ COMMITTED(커밋된 읽기)
- REPEATABLE READ(반복 가능한 읽기)
- SERIALIZABLE(직렬화 가능)
아래로 갈수록 성능은 저하되고, 격리성은 향상
보통 실무에서는 2, 3을 많이 사용
DB 락 개념
원자성을 유지하려면 한 세션이 트랜잭션을 시작하고 데이터를 수정하는 동안에는
커밋이나 롤백 전까지 다른 세션에서 해당 데이터를 수정할 수 없게 막아야 한다.
데이터베이스는 이런 문제를 해결하기 위해 락(Lock)이라는 개념을 제공한다.
A 세션이 트랜잭션을 시작하고 수정중이면 락을 획득하고, B 세션은 수정하지못한다. (락 대기)
A 세션이 커밋하거나 락 타임이 만료되면 락을 반납하고, B 세션이 락을 획득하여 수정할 수 있다.
B 세션이 커밋 후 트랙잭션이 끝나면 락을 반납한다.
"일반적인 조회는 락을 사용하지 않는다."
그런데 금액적으로 매우 중요해서 변경이 생기면 안되는 애플리케이션에서는
조회에서도 락이 필요할 때가 있는데 그럴때는 select for update 구문을 사용하면 된다.
인프런 김영한님의 스프링 DB 1편을 듣고 작성한 글입니다.
'Spring' 카테고리의 다른 글
Spring Security 간단 적용 (0) | 2022.08.01 |
---|---|
자바 예외 이해 (0) | 2022.07.28 |
Spring Boot 와 JWT (0) | 2022.07.20 |
파일 업로드 (0) | 2022.06.26 |
스프링 타입 컨버터 (0) | 2022.06.25 |
댓글