일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 컴퓨터구조
- JPA
- OS
- Kafka
- 자바
- 알고리즘
- 파이썬
- MySQL
- react
- c언어
- Heap
- Spring
- JavaScript
- mongoDB
- redis
- spring webflux
- Java
- MSA
- 디자인 패턴
- Algorithm
- 운영체제
- 네트워크
- design pattern
- Proxy
- IT
- Galera Cluster
- 백준
- Data Structure
- C
- 자료구조
Archives
- Today
- Total
시냅스
Java 트랜잭션 관련 정리 본문
트랜잭션 Transaction 이란
- 트랜잭션은 하나의 거래를 안전하게 처리하도록 보장하는 것을 뜻한다.
- 은행 송금을 예시로 하자면, 송금하는 주체는 돈이 감소해야 하고, 동시에 송금을 받는 주체는 돈이 증가해야 한다.
- 두 트랜잭션이 성공적으로 수행됐다면 commit 해야 하고, 하나라도 실패했다면 rollback해야 한다.
트랜잭션 ACID
- 트랜잭션은 원자성 (Atomicity), 일관성 (Consistency), 격리성 (Isolation), 지속성 (Durability) 를 보장해야 한다.
- 원자성
- 트랜잭션 내에서 실행한 작업은 마치 하나의 작업인 것처럼 모두 성공하거나 실패해야 한다.
- 일관성
- 모든 트랜잭션은 일관성 있는 데이터베이스 상태를 유지해야 한다.
- 예를 들면 데이터베이스에서 정한 무결성 제약 조건을 항상 만족해야 한다.
- 격리성
- 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 격리한다.
- 동시에 같은 데이터를 수정하지 못하는 것과 같다.
- 격리성은 동시성과 관련된 성능 이슈로 인해 트랜잭션 격리 수준(Isolation level) 을 선택할 수 있다.
- 지속성
- 트랜잭션을 성공적으로 끝내면 그 결과가 항상 기록되어야 한다.
트랜잭션 격리 수준 Isolation level
- READ UNCOMMITED 커밋되지 않은 읽기
- READ COMMITTED 커밋된 읽기 - 일반적으로 많이 사용되는 level
- REPETABLE READ 반복 가능한 읽기
- SERIALIZABLE 직렬화 가능
트랜잭션에 대한 이해
- WAS, DB 접근 툴 등 클라이언트에서 DB 서버에 접근할 경우 커넥션이 생길 때마다 각각은 개별 세션을 갖는다.
- 클라이언트에서 SQL을 전달하면 커넥션에 연결된 세션에서 실행한다.
- 트랜잭션은 커밋 또는 롤백을 통해야만 종료할 수 있다.
- 만약 sql을 실행하고 commit 을 호출하지 않았다면 임시로 데이터를 저장하는 것이다.
- 다른 세션에서는 임시로 저장된 데이터는 확인할 수 없다.
- 이러한 특성은 수동 커밋 설정에서만 확인할 수 있다.
- 보통 자동 커밋 모드가 기본으로 설정된 경우가 많기 때문에 수동 커밋 모드로 설정하는 것을 트랜잭션을 시작한다고 표현한다.
- 다른 세션에서는 임시로 저장된 데이터는 확인할 수 없다.
- 만약 sql 실행 중 에러가 발생되면 rollback을 통해 원복해야하는데, 자동 커밋 모드에서는 불가능하다.
- 원자성 (모두 실패하거나 모두 성공해야 한다.)이 지켜져야 한다.
DB 락
- 동시에 같은 데이터를 수정하지 못하도록 하여 데이터 정합성을 지키도록 한다.
- lock은 먼저 접근한 세션에서 commit 하거나 rollback해야 획득할 수 있다.
- 위 사진 5번에서 세션2는 lock을 획득하기 위해 대기한다.
- 대기하는 시간은 설정할 수 있다.
- 세션 1이 6번에서 커밋하여 세션 2가 lock을 획득할 수 있게 한다.
- 일반적으로 조회에서는 사용하지 않지만 select for update 를 통해 lock 을 획득할 수 있다.
실제 적용
- 트랜잭션을 사용하는 동안 같은 커넥션을 유지해야 한다.
- 가장 단순한 방법은 커넥션을 파라미터로 전달해서 같은 커넥션을 유지하도록 하는 것이다.
- 비즈니스 로직이 완료되면 connection 을 닫아주면 된다.
- 다만 JDBC에서 JPA로 기술을 변경하게 되는 경우 트랜잭션 추상화를 이용할 수 있다.
- 트랜잭션 추상화를 이용하면서 connection 과 같은 리소스를 동기화할 필요가 있다.
- 이 때 스프링은 트랜잭션 동기화 매니저를 제공한다.
- 트랜잭션 동기화 매니저는 쓰레드 로컬을 사용하면서 멀티쓰레드 상황에 안전하게 커넥션을 동기화할 수 있게 한다.
- 정리하면
- 1. 트랜잭션 메니저는 데이터소스를 통해 커넥션을 만들고 트랜잭션을 시작한다.
- 2. 트랜잭션 매니저는 트랜잭션이 시작된 커넥션을 트랜잭션 동기화 매니저에 보관한다.
- 3. 레파지토리는 트랜잭션 동기화 매니저에 보관된 커넥션을 꺼내 사용한다.
- 4. 트랜잭션이 종료되면 트랜잭션 매니저는 트랜잭션 동기화 매니저에 보관된 커넥션을 통해 트랜잭션을 종료하고 커넥션 또한 닫는다. ( DataSourceUtils.releaseConnection() )
트랜잭션 프록시
- 서비스 계층에 순수한 비즈니스 로직만 남기기 위해 스프링 AOP를 통해 프록시를 도입할 수 있다.
- 트랜잭션이 필요한 곳에 @Transaciotnal 어노테이션을 붙여 적용시킬 수 있다.
@Transactional
public void accountTransfer(String fromId, String toId, int money) throws SQLException {
bizLogic(fromId, toId, money);
}
'Java, Spring' 카테고리의 다른 글
Spring JdbcTemplate 정리 (0) | 2022.09.02 |
---|---|
Java 예외 관련 정리 (0) | 2022.08.25 |
Java 커넥션 풀과 데이터 소스 (0) | 2022.08.25 |
Java - JDBC 정리 (2) | 2022.08.24 |
Spring MVC 구조 : 핸들러어댑터 ,핸들러 매핑, 메세지 컨버터 handler mapping handler adapter, message converter (0) | 2022.08.02 |
Comments