트랜잭션이란?
여러 SELECT , INSERT , UPDATE , DELETE 작업을 묶어둔
DB의 논리적인 작업 단위.
트랜잭션의 핵심은?
All or Nothing
모두 반영하거나 모두 반영하지 않거나.
트랜잭션의 예
예)
INSERT INTO orders ( user_it , item_id , price , amount )
VALUES ( 177 , 30 , 10000 , 3 )
UPDATE items
SET stock_count = stock_count - 3
WHERE item_id = 30
COMMIT;
원자성(Atomicity)
원자 처럼 더이상 쪼개질 수 없는 작업의 단위다.
2개의 커넥션을 한 트랜잭션으로 묶으려면?
2개의 커넥션은 한 트랜잭션에 묶을 수 없다.
트랜잭션은 커넥션의 하위에 종속된다.

Spring에서 트랜잭션 단위로 묶는 방법은?
@Transactional 애너테이션을 사용한다.
@Service
@Transactional
public class OrdersServiceImpl implements OrderService {
private OrdersRepository ordersRepository;
private ItemsRepository itemsRepository;
}
한 메서드에서 다른 메서드를 호출하여 DB 관련 작업을 수행하면?
@Service
@Transactional
public class OrdersServiceImpl implements OrderService {
private OrdersRepository ordersRepository;
private ItemsRepository itemsRepository;
public void create(orderVO) {
this.ordersRepository.save(orderVO);
this.itemsRepository.stock_decrease(orderVO);
}
}
Spring에서 @Transactional 애너테이션을 사용하면
메서드 내에서 호출된 모든 메서드를 하나의 트랜잭션으로 묶어서 처리한다.
트랜잭션 내에 외부 API에 값을 수정하는 작업이 있다면?

외부 API에 값을 수정하는 작업의 경우
트랜잭션이 적용되지 않기 때문에
Rollback 시에는
외부 API의 값을 원래대로 수정해야 한다.
여러 종류(Oracle,MySQL)의 DB를 한 트랜잭션에 묶으려면?

글로벌 트랜잭션을 사용하면 한 트랜잭션에 묶을 수 있다.
하지만 성능 이슈로 인해서 잘 사용하지 않는다.
경쟁상태(Race Condition)
여러 클라이언트가 동시에 같은 데이터에 접근한 상황.
경쟁상태의 예
당직자가 최소 1명은 남아 있어야 한다.
당직자 명단은 DB 조회를 통해서 확인할 수 있다.
마티와 찰스는 집에 가고 싶은 마음에 당직자를 조회해 본다.

둘은 동시에 남은 당직자를 조회하여 2명이 남은 것을 확인하고
자신을 당직자에서 제회하는 update문을 실행한다.
결과적으로 당직자가 0명이 되는 일이 발생하였다.
트랜잭션 격리(Isolation)
트랜잭션을 서로 격리해서 다른 트랜잭션에 영향을 주지 못하게 함으로써
경쟁상태로 인해서 발생하는 문제점들을 해결한다.
트랜잭션 격리수준(Isolation Level)
Serializable(직렬화)
트랜잭션 작업들을 완전히 독립시켜서
하나의 트랜잭션이 작업 중일 때 다른 트랜잭션은 접근을 할 수 없게 한다.

한 트랜잭션이 진행 중이면
다른 모든 트랜잭션 작업들은 대기해야 한다.
병렬처리가 불가하기 때문에 처리 속도가 오래걸린다.
속도의 문제로 DB에서 사용하지 않는 트랜잭션 격리 수준이다.
Read Committed
- 한 트랜잭션에서 [ 특정 행(row) ]을 INSERT , UPDATE , DELETE를 실행한 경우
COMMIT을 하기전까지는 다른 트랜잭션에서는 [ 특정 행(row) ]의 이전 상태를 SELECT만 할 수 있고
[ 특정 행(row) ]을 INSERT , UPDATE , DELETE는 할 수 없다.
- Oracle에서 사용하는 격리수준이다.

Repeatable Read
- 한 트랜잭션에서 [ 특정 행(row) ]을 INSERT , UPDATE , DELETE를 실행한 경우
COMMIT을 하기전까지는 [ 특정 행(row) ]을 INSERT , UPDATE , DELETE는 할 수 없다.
- 트랜잭션을 시작 지점에서 버전을 생성하고
버전 내에서 수행한 INSERT , UPDATE , DELETE 내역을 SELECT 할 수 있다.
- MySQL이 사용하는 격리수준이다.

Read Uncommited
- Commit 되지 않은 변경사항도 읽을 수 있다.
- 경쟁상태로 인해 발생하는 모든 문제가 그대로 발생하기 때문에
DB의 트랜잭션 격리 수준으로 사용하지 않는다.
격리수준 적용으로 해결되는 문제 - Dirty Read
- Dirty Read

- Dirty Read를 해결

'MySQL' 카테고리의 다른 글
| [ MySQL ] DBMS의 검색 속도 (0) | 2022.09.18 |
|---|---|
| [MySQL] DBMS의 데이터 검색 절차 (0) | 2022.09.18 |
| [ MySQL ] 쿼리 최적화 (0) | 2022.02.10 |
| [ MySQL ] Auto Increment 설정하기 (0) | 2022.01.04 |
| [ MySQL ] 백업 관리하기. (0) | 2021.12.08 |
