데이터베이스/JDBC
[JDBC #3] 순수 JDBC와 트랜잭션 이해하기
거북이의 기술블로그
2024. 11. 5. 00:39
1. 트랜잭션 ACID
2. 트랜잭션 격리 수준
3. DB 세션 이해하기
4. 순수 JDBC 트랜잭션 사용기
트랜잭션 ACID
- 원자성 (Atomicity)
- 트랜잭션 내에서 실행한 작업들은 모두 성공하거나 모두 실패
- 일관성 (Consistency)
- 일관성 있는 데이터베이스 상태 유지 (무결성 제약 조건을 항상 만족)
- 격리성 (Isolation)
- 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않아야함
- 지속성 (Durability)
- 트랜잭션을 성공적으로 끝내면 그결과가 항상 기록되어야함
트랜잭션 격리 수준
- READ UNCOMMITED (커밋되지 않은 읽기)
- READ COMMITTED (커밋된 읽기)
- REPEATABLE READ (반복 가능한 읽기)
- SERIALIZABLE (직렬화 가능)
일반적으로, READ COMMITED(커밋된 읽기)가 기본적으로 사용된다
DB 세션
1. DB 세션 이란?
- DB 세션은 클라이언트(애플리케이션 또는 사용자)가 데이터베이스에 접속하여 명령(SQL)을 실행하고 응답을 받을 수 있는 하나의 작업 흐름이다.
- 보통 하나의 커넥션이 하나의 세션과 매핑된다.
- SQL 실행, 트랜잭션 처리, 임시 테이블 등은 세션을 통해 관리된다.
2. DB 세션 구성 요소
구성 요소 | 설명 |
커넥션(Connection) | 클라이언트와 DB 사이의 연결. 세션은 커넥션이 존재할 때 유지된다. |
사용자 정보 | 로그인한 사용자 계정 정보, 권한 |
트랜잭션 상태 | 현재 진행 중인 트랜잭션이 있다면 그 상태 유지 |
세션 변수 | 사용자 설정 정보, 언어 설정 등 |
3.세션은 언제 생성되고 언제 종료되나?
- 생성: 클라이언트가 DB에 로그인하거나 커넥션을 맺는 순간
- 유지: 커넥션이 살아 있는 동안 세션도 유지됨
- 종료: 커넥션이 close() 되거나 타임아웃이 발생하면 세션도 종료됨
4. 예시
- 데이터베이스는 내부적으로 커넥션 요청에따른 세션을 유지하게 된다.
- 일반적으로 조회의 경우, 트랜잭션이 필요 없을수 있지만 "수정/삭제/생성"에 있어서는 유지되어야하기에 세션A와 세션B가 작업적으로 독립적이어야 한다
순수 JDBC 트랜잭션 사용기
DB와 연결을 도와주는 인터페이스의 경우, 특별한 설정이 없다면 AutoCommit이 활성화 되어있다.
(* 트랜잭션 과정은 ACID의 규칙에 따라 모든 과정이 끝난 후에 처리되어야하므로 AutoCommit은 false로 두어야한다.)
public void txSaveAfterDelete(Map<String, Object> params) throws Exception{
Connection con = DBConnectionUtil.getConnection();
con.setAutoCommit(false);
try{
Member oldMember = memberRepository.findByName(params.get("oldName").toString()).orElseThrow(
() -> new RuntimeException("no find member")
);
Member uptMember = new Member();
uptMember.setName(params.get("name").toString());
uptMember.setAge(Integer.parseInt(params.get("age").toString()));
uptMember.setAddr(params.get("addr").toString());
// 1. delete 후 save()
txMemberRepository.txDelete(con,oldMember.getName());
txMemberRepository.txSave(con, uptMember);
con.commit();
}catch(Exception e){
con.rollback();
throw new RuntimeException("[TRANSACTION] 실패로 인한 rollback");
}finally {
con.setAutoCommit(true);
if (con != null) con.close();
}
}
- 설명
- try ~ catch를 활용한 commit(), rollback() 수행
- DB 세션 락을 자연스럽게 사용 (다른 세션이 사용하지 못함 - 대기상태)
- 단점
- 코드가 복잡하다 (서비스 계층이 복잡해진다)
- Connection의 경우, Repository층에서 닫을 경우 세션이 달라지는 일이 발생하므로 꼭 트랜잭션이 행해지는 구간에서 Connection 리소스를 해제해야함.
- AutoCommit모드를 수동으로 관리해야하는 불편함이 존재