두 사람이 수량 6개인 주문을 열었다. 한 사람은 7개로, 다른 사람은 9개로 바꾼다. 나중에 저장한 값만 남기면 먼저 고친 사람의 판단이 사라질 수 있다.

이 상황을 실제 회사 자료 없이 로컬 SQLite의 두 연결로 재현했다. 기존 예제의 수정 번호 비교를 넘어서 비교와 쓰기가 어느 경계에서 함께 이루어져야 하는지 확인한 제작 기록이다.

먼저 읽은 값과 지금 저장된 값을 구별했다

편집 화면에서 읽은 버전은 사용자가 판단한 출발점이다. 저장 순간 DB의 버전은 다른 사람이 작업했는지를 알려 준다. 이번 명령에는 expected_version을 넣고 트랜잭션 안에서 읽은 현재 버전과 비교한다. 두 값이 다르면 수량을 바꾸지 않고 version_conflict를 돌려준다. 누가 최신 번호인지 사용자가 추측하게 두지 않았다.

비교를 한 뒤 트랜잭션 밖에서 저장하면 그 사이에 또 다른 쓰기가 들어올 수 있다. 그래서 확인과 갱신을 같은 쓰기 경계에 두었다. 이전 자료 가져오기 모듈의 순수 번호 비교가 DB 잠금을 구현한 것이 아니라는 설명을 실제 로컬 실험으로 확장한 부분이다. 상태 비교 함수와 저장소의 보장을 같은 것으로 부르지 않는다.

두 연결을 같은 출발선에서 실행했다

테스트는 수량 7개와 9개를 쓰는 두 작업을 만들고 둘 다 버전 0을 예상하게 했다. 각 작업은 별도의 SQLite 연결을 사용하며 시작 장벽 뒤에서 실행된다. 한 작업이 쓰기 트랜잭션을 잡고 버전을 올리면 다음 작업은 바뀐 버전을 읽는다. 검사에서는 정확히 한 작업만 성공하고 성공 사건도 하나인지 확인했다.

어느 수량이 먼저 저장될지는 실행 순서에 따라 달라질 수 있다. 그래서 승자가 반드시 7개여야 한다는 검사를 만들지 않았다. 지켜야 할 것은 하나의 예상 버전으로 서로 다른 두 변경을 조용히 모두 수용하지 않는 조건이다. 동시 실행 결과를 확인할 때 우연히 정해지는 순서와 유지해야 할 규칙을 구분했다.

충돌은 사용자의 입력을 버리라는 뜻이 아니다

서버가 수정을 거절해도 두 번째 사용자가 작성한 9개는 검토할 가치가 있다. 실무 화면에서는 현재 저장된 값과 내가 작성한 초안을 함께 보여 주고 다시 판단하게 하는 편이 좋다. 최신 버전 번호만 받아 자동으로 덮어쓰면 충돌을 알린 의미가 사라진다. 나는 충돌 결과를 자동 재시도의 성공 조건으로 다루지 않기로 했다.

공유 모듈은 화면의 초안을 보관하지 않고 DB가 어떤 변경을 거절하는지까지 구현한다. 브라우저의 초안과 비교 화면은 연결할 별도 책임이다. 다른 입력 모듈에서 이미 다뤘던 임시 보관과 서버 저장의 차이를 유지해야 한다. 이 글의 코드 검증을 실브라우저에서 입력을 잃지 않는 검수로 넓혀 보고하지 않는다.

잠금 대기와 버전 충돌도 서로 다르다

버전 충돌은 다른 변경이 저장됐다는 업무 결과다. DB가 바빠 제한 시간 안에 잠금을 얻지 못하는 것은 저장소 접근의 결과다. 이번 실험은 연결에 제한 시간을 두지만 잠금 오류를 무한히 재시도하지 않는다. 화면에서는 현재 결과를 확인할 경로가 필요하며 저장되지 않은 입력은 보존해야 한다. 모든 실패를 같은 다시 저장 버튼으로 처리해서는 안 된다.

SQLite의 쓰기 직렬화는 이 로컬 구성의 특징이다. 다른 데이터베이스를 쓴다면 조건부 갱신의 영향 행 수나 해당 저장소의 트랜잭션 계약을 확인해야 한다. 파일을 잠갔다는 말로 여러 서버의 모든 외부 작업을 해결했다고 설명하지 않는다. 재사용할 것은 확인과 쓰기의 경계를 함께 설계하는 질문이지 특정 잠금 문법 하나가 아니다.

합칠 수 있는 변경인지도 업무가 결정한다

한 사람은 메모를, 다른 사람은 수량을 바꿨다면 자동으로 합칠 수 있을까. 필드가 다르다는 이유만으로 안전하다고 정할 수는 없다. 메모가 납기나 승인 조건에 영향을 줄 수도 있기 때문이다. 어떤 필드는 독립적으로 합치고 어떤 변경은 재확인이 필요한지 회사의 업무 계약으로 정해야 한다. 이번 예제는 조용한 병합 대신 충돌을 명확히 드러낸다.

패키지는 순차 충돌, 두 연결의 동시 수정, 실제 남은 수량과 사건 수를 시험한다. 성공한 저장과 변경 이력이 함께 남는 조건도 같은 DB에서 확인했다. 독립 합성 자료의 결과이며 회사 운영 DB를 바꾼 실험은 아니다. 독자가 자기 저장소와 화면에 맞춰 확장할 때 확인해야 할 지점을 이 경계에서 찾을 수 있다.