1️⃣ 원자적(Atomic)의 정확한 의미
원자적 연산이란?
더 이상 쪼갤 수 없는 하나의 작업 단위
중간 상태가 외부에 절대 보이지 않고
“전부 실행되거나, 전혀 실행되지 않거나” 둘 중 하나만 발생하는 연산
쉽게 말하면
중간에 끼어들 틈이 없다
라는 뜻이야.
2️⃣ 우리가 만든 방식이 왜 "원자적"이냐?
지금 만든 쿼리:
update article
set view_count = view_count+1
where id= ?
이게 원자적 연산이다.
DB 내부 관점에서 보면
이 한 줄은 DB 엔진이 내부적으로:
- 현재 view_count 읽기
- +1 계산
- 결과 다시 쓰기
를 하나의 락 단위 / 하나의 실행 단위로 처리한다.
👉 다른 트랜잭션이 중간에 끼어들 수 없다.
즉,
read → 계산 → write
이게 DB 엔진 안에서 하나의 원자 작업으로 묶여서 실행됨.
3️⃣ 원자적이지 않은 방식 (문제 발생 패턴)
일부러 피한 방식:
Article article = findById(id);// SELECT
article.setViewCount(article.getViewCount() +1);
save(article);// UPDATE
이걸 DB 관점으로 풀면:
요청 A
SELECT view_count=0
요청 B (거의 동시에)
SELECT view_count=0
요청 A
UPDATE view_count=1
요청 B
UPDATE view_count=1
결과
- 실제 요청 수: 2
- DB 결과: 1 ❌
왜 발생?
이 과정이:
SELECT
→ Java 메모리에서 계산
→ UPDATE
이렇게 "여러 단계"로 쪼개져 있기 때문
👉 원자적이지 않음
4️⃣ 내 방식은 뭐가 다른데?
내 방식:
incrementViewCount(id);
실제 SQL:
update article
set view_count= view_count+1
where id= ?
요청 A
DB 내부에서:
view_count = view_count + 1
요청 B (동시에 와도)
DB 내부에서:
view_count = view_count + 1
결과
0 → 1 → 2
👉 누락 없음
5️⃣ "벌크 업데이트"와 "원자성"은 다른 개념이다
너가 말한 이 부분 중요함:
"벌크성 쿼리인 건 알겠는데…"
벌크(Bulk)
= 여러 row를 한 번에 처리할 수 있는 쿼리 방식 (성능/실행 방식 개념)
원자성(Atomic)
= 동시성 안전성 개념
관계는 이렇다:
모든 벌크 업데이트가 원자적인 건 아님
하지만
col = col + 1 같은 DB 내부 연산은 원자적으로 처리됨
6️⃣ 왜 DB는 원자성을 보장할 수 있냐?
DB는:
- Row-level Lock
- MVCC
- Transaction Isolation
같은 메커니즘으로
같은row를 동시에 수정할 때
→ 내부적으로 순서를 직렬화
한다.
그래서:
A가 먼저 +1
B가 그 다음 +1
형태로 자동 정렬(serialization) 된다.
7️⃣ 테스트가 원자성을 "증명"한 거야
테스트:
threadCount = 100;
동시에 100번 호출했는데:
assertThat(updated.getViewCount()).isEqualTo(100);
통과함.
이 의미는:
"동시 요청이 와도 +1 연산이 중간에 깨지지 않고
하나씩 정확히 누적되었다"
👉 즉 원자성 보장 확인
'프로젝트 > 스프링 부트 3 백엔드 개발자 되기 Blog + 선착순 강의 프로젝트' 카테고리의 다른 글
| 👥🚨 좋아요 동시성 테스트에서 교착상태가 발생한 이유와 해결 방법 (0) | 2026.02.14 |
|---|---|
| 👥🚨 좋아요 토글을 빠르게 연타하면 깨지는 이유와 해결 방법 (프론트 + 백엔드 동시성 정리) (0) | 2026.02.14 |
| 👥💡 조회수 동시성 문제 해결(원자적) (0) | 2026.02.14 |
| 👥💡 Spring Data JPA + Querydsl 커스텀 Repository 구조 정리 (0) | 2026.02.14 |
| 👥💡 Querydsl 페이징: fetchResults()가 비권장(Deprecated)된 이유와 실무 정석 패턴 (0) | 2026.02.14 |