데이터베이스 연결 구조

- 사용자는 WAS나 DB 접근 툴(sqldeveloper 등) 같은 클라이언트를 사용하여 데이터베이스 서버에 접근하여 연결을 요청하고 커넥션을 맺음
- 이때, 데이터베이스 서버 내부에 세션이라는 것이 생성되어 해당 커넥션을 통한 모든 요청은 이 세션을 통해서 실행
- 개발자가 클라이언트를 통해 SQL을 전달하면 현재 커넥션에 연결된 세션이 SQL을 실행
- 세션은 트랜잭션을 시작하고 커밋/롤백을 통해 트랜잭션 종료
- 사용자가 커넥션을 닫거나 DBA가 세션을 강제로 종료하면 세션은 종료됨
- 커넥션 풀이 10개의 커넥션을 생성하면, 세션도 10개 생성
자동 커밋과 수동 커밋
set autocommit true: 자동 커밋 모드 설정- SQL 실행 이후
commit을 호출하지 않아도 자동으로 커밋됨 commit을 호출하지 않는다고 하여 트랜잭션이 실행되지 않는 것이 아니라, 자동으로commit을 호출함으로써 SQL 실행마다 트랜잭션이 시작되고 종료되는 것
- SQL 실행 이후
set autocommit false: 수동 커밋 모드 설정- 보통 자동 커밋 모드가 기본을 설정된 경우가 많아, 수동 커밋 모드로 설정하는 것을 트랜잭션을 시작한다고 표현할 수 있음
- 수동 커밋 설정을 하면 반드시
commit또는rollback을 호출해야 함
DB 락
한 세션의 트랜잭션이 실행되는 동안 다른 세션의 트랜잭션이 현재 실행 중인 트랜잭션의 데이터에 접근하지 못하도록 하는 것
- 공유 락(Shared Lock) : 여러 트랜잭션이 동시에 같은 데이터를 SELECT 가능하지만, UPDATE는 불가
- 배타 락(Exclusive Lock) : 한 트랜잭션만 접근 가능, 다른 트랜잭션은 SELECT, UPDATE 모두 불가
세션 1이 트랜잭션을 시작하고 데이터를 수정하는 동안, 아직 커밋을 수행하지 않았는데 세션 2가 같은 데이터를 수정하게 되면 트랜잭션의 원자성이 깨지는 문제가 발생
이를 방지하기 위해 '락'을 사용
1. 데이터 동시 접근

- 세션 1, 2 모두 memberA의 금액을 변경하려는 상황
- 동시에 같은 데이터에 접근함으로써 발생하는 문제를 방지하기 위해 '락' 사용
2. 세션1 트랜잭션 시작 및 SQL 실행

- 세션1이 세션2보다 조금 더 빨리 요청했다고 가정하면 세션1이 memberA 로우의 락을 획득
- 접근하려는 로우의 락을 갖고 있어야 해당 로우를 수정 가능
- 세션1이 트랜잭션을 시작하여 해당 로우에 update sql 실행
3. 세션2 트랜잭션 시작

- 세션2가 트랜잭션을 시작하여 memberA의 money를 변경하려 시도
- 해당 로우의 락은 이미 세션1이 갖고 있으므로 락이 반환될 때 까지 대기
- 락 대기 시간을 넘어가면 락 타임아웃 오류 발생
4. 세션1 락 반환

- 세션1이 커밋을 수행함에 따라 트랜잭션이 종료되었으므로 락 반환
5. 세션2 락 획득

- 세션1의 트랜잭션 종료로 인해 반환된 락을 세션2가 획득
6. 세션2 SQL 실행

- 세션2는 락을 갖고 있으므로 memberA 로우에 접근하여 SQL 실행
7. 세션2 트랜잭션 종료

- 세션2는 커밋을 수행하고 트랜잭션이 종료되었으므로 락을 반납
'Spring' 카테고리의 다른 글
| [Spring] Spring DB : Spring 트랜잭션 적용 - 기존 코드의 문제점 (0) | 2024.08.17 |
|---|---|
| [Spring] Spring DB : 애플리케이션 코드에 트랜잭션 적용 (0) | 2024.08.07 |
| [Spring] Spring DB : 트랜잭션 이해 (0) | 2024.08.05 |
| [Spring] Spring DB : Connection Pool 과 DataSource (0) | 2024.08.01 |
| [Spring] Spring DB : JDBC를 사용한 데이터베이스 연결 (0) | 2024.07.30 |