공유 락(LS, Shared Lock)
- Read Lock라고도 하는 공유락은 트랜잭션이 읽기를 할 때 사용하는 락입니다.
- 데이터를 읽기만하기 때문에 같은 공유락 끼리는 동시에 접근이 가능하다는 장점이 있습니다
- 다만, 동시에 읽을 수는 있으나, 변경은 안되며, 공유 락이 걸리면 배타 락을 걸 수 없습니다.
배타 락(LX, Exclusive Lock)
- Write Lock라고도 하는 베타락은 데이터를 변경할 때 사용하는 락입니다.
- 배타락은 트랜잭션이 완료될 때까지 유지되며, 베타락이 끝나기 전까지 어떠한 접근도 허용하지 않습니다.
- 다만, 배타 락이 걸리면 어떠한 락도 걸 수 없습니다.
데드락(Deadlock)
- 데드락은 두 개 이상의 트랜잭션이 서로가 소유한 자원을 기다리면서 무한히 대기하는 상태를 말합니다.
- 데드락은 Coffman의 네 가지 조건이 모두 만족될 때 발생합니다.
데드락 발생 조건 (Coffman 조건 4가지)
- 상호 배제(Mutual Exclusion): 자원은 하나의 트랜잭션만 점유할 수 있습니다.
- 점유 및 대기(Hold and Wait): 자원을 점유한 상태에서 다른 자원을 요청할 수 있습니다.
- 비선점(Non-Preemptive): 점유한 자원을 강제로 회수 불가합니다.
- 순환 대기(Circular Wait): 트랜잭션 간 자원 요청이 원형으로 연결되어 있습니다.
데드락 해결 방법
타임아웃(Timeout)
- 이를 해결하기 위해 트랜잭션 타임아웃(timeout) 설정을 하여 일정 시간 자원 획득 실패시 트랜잭션을 자동 중단 시키는 것입니다.
- Spring에서는 @Transactional(timeout = X) 또는 커넥션 풀(HikariCP)의 connectionTimeout 설정으로 구현합니다.
@Service
@RequiredArgsConstructor
public class BankService {
private final BankAccountRepository bankAccountRepository;
@Transactional(timeout = 5) // 락 대기 시간 5초
public void withdrawMoney(UUID accountId, BigDecimal withdrawAmount) {
BankAccount account = bankAccountRepository.findByIdForUpdate(accountId)
.orElseThrow(() -> new EntityNotFoundException("Account not found"));
account.withdraw(withdrawAmount);
}
}
결론
데이터베이스 락은 트랜잭션 간 동시성 제어를 위해 사용하며, 공유락과 배타락이 있습니다. 공유락은 데이터를 읽을 때 사용하는 락으로 동시에 여러 트랜잭션이 읽기는 가능하지만 쓰기는 차단됩니다. 반면 배타락은 데이터를 수정할 때 사용하는 락으로 해당 자원에 대해 트랜잭션 읽기 쓰기 모두 차단합니다.
다만 이러한 락 제어에 있어 두 개 이상의 트랜잭션이 서로 점유한 자원을 무한히 대기하면서 데드락이 발생할 수 있으며, 해결 방법으로는 트랜잭션에 타임아웃을 설정하여 일정 시간 내에 락을 획득하지 못하면 트랜잭션이 자동 중단되도록 하여 데드락을 회피할 수 있습니다,
'CS' 카테고리의 다른 글
CS 스터디 34 - 객체지향 프로그래밍 (OOP) (0) | 2025.07.18 |
---|---|
CS 스터디 (DB) 26 - 클러스터링과 레플리케이션에 대해 설명해주세요. (0) | 2025.05.26 |
CS 스터디 (DB) 24 - 트랜잭션 격리 수준에 대해 설명해주세요. (0) | 2025.05.23 |
CS 스터디 (DB) 23 - 트랜잭션의 특성은 무엇인가요? (0) | 2025.05.23 |
CS 스터디 (DB) 22 - 옵티마이저란 무엇인가요? (0) | 2025.05.23 |