| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
- design pattern
- OS
- JavaScript
- 알고리즘
- IT
- JPA
- Spring
- 네트워크
- 파이썬
- react
- Road to Web3
- Blockchain
- Galera Cluster
- 컴퓨터구조
- Java
- mongoDB
- 디자인 패턴
- MSA
- Heap
- 자료구조
- 백준
- C
- Ethereum
- Algorithm
- Data Structure
- 자바
- spring webflux
- 운영체제
- MySQL
- redis
- Today
- Total
시냅스
Road to Web3 (12) 블록체인 동시성: 락 대신 전역 직렬화 + nonce 조건부 커밋 본문
Road to Web3 (12) 블록체인 동시성: 락 대신 전역 직렬화 + nonce 조건부 커밋
ted k 2026. 1. 1. 10:41이 글은 Ethereum 및 EVM 계열을 기준으로 설명합니다.

이번 편의 목표는 web2 락킹 사고를 체인식으로 변환하는 것입니다.
- 동시성 이슈가 없는가라는 질문에 대답하기
- 락 대신 순서 결정이 핵심이라는 점을 잡기
- nonce와 조건부 커밋을 제품과 운영 감각으로 연결하기
Web2 개발자인 제가 바라봤던 블록체인은 이랬습니다.
- 체인은 분산 시스템이니 레이스 컨디션 지옥일 것이다
- 그러니 뭔가 분산 락 같은 게 있겠지
- 아니면 결국 중앙화 서버가 순서를 정하겠지
하지만 EVM 계열의 기본 해법은 단순합니다.
- 모든 상태 변경을 전역 순서로 직렬 실행한다
락을 쓰지 않는 대신, 전 세계가 같은 커밋 로그 순서를 공유하는 모델입니다.
요약
| web2 개념 | 체인 개념 |
|---|---|
| 동시 요청 | mempool에 동시에 들어오는 tx |
| 트랜잭션 격리 수준 | 선택 불가, 체인이 정한 순서가 전부 |
| row lock | 없음, 대신 전역 직렬화 |
| optimistic lock version | nonce, 그리고 상태 기반 require |
| 조건부 업데이트 where version = v | require와 revert |
| idempotency key | nonce와 서비스 레벨 상태 머신 |
1) 동시성 문제는 없다가 아니라, 다르게 나타난다
블록체인도 동시성이 있습니다.
- 전 세계에서 동시에 트랜잭션이 날아온다
- 노드마다 멤풀이 다르다
- 네트워크 전파 지연이 있다
하지만 중요한 건 상태 커밋 시점입니다.
- 블록에 포함된 트랜잭션은 정해진 순서로 실행된다
- 모든 노드는 그 순서대로 동일한 결과를 재현해야 한다
그래서 체인의 동시성 문제는
- 동시에 실행해서 충돌하는 문제라기보다
- 어떤 순서로 실행되느냐에 따라 결과가 달라지는 문제
로 변환됩니다.

2) 전역 직렬화는 누가 하나
블록을 제안하는 주체가 후보 순서를 만들고, 합의가 그 순서를 확정합니다.
- 제안자 proposer 또는 시퀀서 L2
- 빌더 builder 선택적 개념
- 밸리데이터들이 합의로 블록을 채택
결과적으로 전역 순서는
- 한 블록 안의 트랜잭션 순서
- 블록이 체인에 붙는 순서
의 합성입니다.
이 순서는 곧 커밋 로그 순서입니다.
3) nonce: 계정 단위의 직렬화 키
EOA 트랜잭션에는 nonce가 있습니다.
- 주소가 지금까지 보낸 트랜잭션 카운터
- 같은 주소의 tx는 nonce 순서대로만 실행 가능
그래서 이런 일이 가능합니다.
- A nonce 7 이 pending이면
- B nonce 8 은 실행이 안 된다 줄이 막힌다
- A를 더 높은 수수료로 대체하면 A`가 먼저 처리된다
web2로 치면
- 한 사용자에 대한 단일 워커 큐
- 또는 파티션 키가 사용자 ID인 로그 스트림
같은 느낌입니다.

4) 조건부 커밋: require가 체인의 optimistic lock이다
nonce는 같은 계정 내 순서만 해결합니다.
진짜 경쟁은 공유 상태에서 터집니다.
e.g. 한 좌석을 두 사람이 동시에 예약
체인은 둘 다 받아주지만, 실행 순서에 따라
- 먼저 실행된 tx가 좌석을 차지하고
- 나중 tx는 require 조건에서 실패하고 revert 된다
이게 체인식 동시성 해결입니다.
즉 락을 걸어 막는 게 아니라
- 먼저 커밋한 사람이 이긴다
- 나머지는 실패하고 롤백된다
web2의 optimistic lock과 매우 닮았습니다.
- update seats set status = sold where id = X and version = v
- 성공 1건, 나머지 0 row updated
컨트랙트에서는
- require seatAvailable
- seatAvailable = false
가 됩니다.
참고
nonce는 노드별 로컬 카운터가 아니라 체인 상태에 저장되는 계정 전역 카운터입니다. 같은 주소에서 nonce가 같은 트랜잭션을 2개 만들면 B와 C가 병렬로 둘 다 커밋되는 게 아니라, 같은 nonce 슬롯을 두 후보가 경쟁하는 구조가 됩니다. 블록에는 둘 중 하나만 포함되고, 먼저 포함된 쪽이 nonce를 소비하면 다른 하나는 대개 무효가 되거나 멤풀에서 제거됩니다. web2로 비유하면 단일 row의 version 값을 들고 update where version = v를 동시에 날린 상황과 같아서, 하나만 성공하고 다른 하나는 충돌로 실패합니다. 즉 nonce는 병렬 실행을 허용하는 값이 아니라, 한 계정의 순서를 강제하는 직렬화 키입니다.
참고: proposer가 1명이어도 분기는 잠깐 생긴다
슬롯마다 proposer가 1명인 건 이상적인 모델이고, 현실에서는 네트워크 지연이나 동시 전파 때문에 같은 슬롯에서 블록 후보가 2개 이상 보이는 순간이 생길 수 있습니다. 이때 최종적으로 한 블록만 남기는 건 proposer의 단일성이라기보다, 밸리데이터들의 투표와 fork choice 규칙이 더 많은 지지를 받은 체인을 정답으로 고르기 때문입니다.
예를 들어 주소 X가 nonce N+1로 B와 C를 동시에 만들었다고 할 때 어떤 노드는 멤풀에 B만 있고, 어떤 노드는 C만 있을 수 있으며, 여러 builder도 각각 B 포함 블록, C 포함 블록 후보를 만들 수 있습니다. 하지만 합의가 진행되면 특정 proposer가 제출한 한 후보가 더 넓게 전파되고 더 많은 투표를 받아 정답 체인이 되며, 결과적으로 체인에는 B 또는 C 중 하나만 남고 다른 하나는 무효 처리되거나 멤풀에서 정리됩니다.

5) 그래서 체인에서는 락이 아니라 실패 처리가 핵심이다
web2에서는 충돌을 락으로 예방하고, 성공 확률을 높입니다.
체인에서는 충돌을 허용하고, 실패를 정상 흐름으로 받아들입니다.
이때 제품 설계가 해야 하는 일은
- 실패를 유저에게 자연스럽게 보여주기
- 실패 시 다음 액션 재시도 취소 대체 선택지 제공
- 오프체인 상태 머신과 멱등성 키로 중복 제공 방지
결국 락 비용을 사용자 경험과 운영 정책으로 바꾸는 작업입니다.
6) 순서 경쟁이 생긴다: MEV 맛보기
순서가 결과를 바꾸면, 순서가 돈이 됩니다.
- 같은 기회에서 누가 먼저 들어가느냐
- 누가 중간에 끼어드느냐
이게 MEV의 출발점입니다.
이번 편에서는 깊게 들어가진 않고, 순서가 경제를 만든다는 것만 기억하면 충분합니다.
7) 체크리스트
1) 동시성은 없지 않다, 순서 문제로 바뀐다
2) 한 블록 안에서 순서가 결과를 바꾼다
3) EOA는 nonce로 계정 내 직렬화가 강제된다
4) 공유 상태 경쟁은 require 조건부 커밋으로 해결한다
5) 실패는 예외가 아니라 정상 상태다
6) 실패 비용 가스를 제품 정책에 반영한다
7) 재시도는 same nonce replacement와 new nonce 재시도를 구분한다
8) pending이 선행이면 뒤 nonce가 막힌다
9) 서비스는 상태 머신과 멱등성으로 중복 제공을 막는다
10) 인덱서는 reorg와 중복을 전제로 한다
11) 순서 경쟁이 곧 MEV로 이어질 수 있다
12) 사용자에게 포함과 확정을 분리해 노출한다
결론
- 체인은 락이 아니라 전역 직렬화로 충돌을 푼다
- nonce는 계정 단위 직렬화 키다
- require는 공유 상태에서 조건부 커밋을 만들어 optimistic lock처럼 동작한다
- 그래서 실패 처리와 UX가 곧 동시성 제어다
'Road To Web3 > Blockchain' 카테고리의 다른 글
| Road to Web3 (14) L2 롤업 구조: 시퀀서, 소프트 확정 vs L1 하드 확정 (0) | 2026.01.01 |
|---|---|
| Road to Web3 (13) 이벤트 로그로 보는 온체인에서 오프체인 연동: 인덱싱과 캐싱이 왜 필요한가 (0) | 2026.01.01 |
| Road to Web3 (11) 실패하는 트랜잭션도 비용이 든다: revert와 운영비 (0) | 2026.01.01 |
| Road to Web3 (10) 스마트컨트랙트는 DB 트랜잭션 함수다 (0) | 2025.12.29 |
| Road to Web3 (9) 토큰 vs 네이티브 코인: USDC는 있는데 왜 전송이 안 되죠 (0) | 2025.12.29 |
