두 채널 사이의 틈은 속도로 메워지지 않습니다. 그것을 메우는 것은, 각자 자신만 믿는 여러 개의 복사본이 아니라 모든 채널이 하나의 재고 풀을 읽는 구조입니다.
더블 부킹의 거의 모든 경우는 시스템이 느려서 생기는 것이 아닙니다. 같은 방이 여러 곳에 동시에 기록되고, 각 장소가 자기 복사본만 신뢰하기 때문에 생깁니다. 진실이 여러 버전으로 존재하는 한, 두 버전이 어긋나는 순간은 반드시 찾아옵니다 — 속도는 그 순간을 짧게 만들 뿐, 없앨 수는 없습니다.
토요일 밤 마지막 남은 객실 하나가 두 채널에 동시에 올라가 있는 상황을 떠올려보세요. 두 손님이 몇 초 간격으로 예약합니다. 각 채널은 자기만의 가용 재고 복사본을 확인하고 방이 비어 있다고 보고 예약을 받아들입니다. 마감 지시가 두 번째 채널에 도달할 즈음, 두 번째 예약은 이미 성립된 상태입니다.
누구도 잘못한 것이 없습니다. 두 채널 모두 설계된 대로 동작했습니다. 실패는 구조에 있습니다 — 두 시스템이 같은 방을 동시에 자기 것으로 믿도록 허용된 것입니다.
iCal로 캘린더를 연동하는 것은 대부분의 사람이 거치는 첫 단계이며, 그 자체로 합리적입니다. 하지만 iCal은 풀(pull) 방식입니다 — 상대 쪽이 자신의 일정에 따라 캘린더 파일을 가져가며, 보통 수십 분 간격이고 플랫폼이 바쁠 때는 더 길어집니다. 즉각적이지 않으며, 보장도 없습니다.
iCal에서 실제 실시간 연결로 바꾸면 이 틈이 몇 분에서 몇 초로 크게 줄어듭니다. 이것은 진짜 개선이며 대부분의 사고를 없애줍니다. 하지만 근본 원인을 없애지는 못합니다. 푸시 방식 설계는 여전히 여러 개의 복사본이 존재하고, 사후에 그것들을 맞추고 있다는 뜻이기 때문입니다.
속도로 해결할 수 없는 더 은밀한 실패도 있습니다. 일부 채널은 재고에 자체적인 자동 조정을 적용합니다 — 예를 들어 취소가 들어오면 방을 자동으로 다시 열어주는 식입니다. 당신의 시스템이 채널이 자기 증감값을 적용하는 그 순간에 절대값을 기록하면, 두 작업의 순서가 뒤바뀔 수 있고 결과가 실제보다 더 많이 나타나는 경우가 생깁니다.
구조적인 해법은 복사본을 두는 것을 멈추는 것입니다. 가용 재고는 실제 객실이라는 단 하나의 풀에서 계산되고, 각 채널은 그 일부를 소유하는 것이 아니라 그 풀을 들여다보는 하나의 뷰일 뿐입니다. 어디서 예약이 들어오든 그 풀은 줄어들고, 모든 채널은 새로운 수치에 맞춰 보정됩니다.
마지막 항목은 보이는 것보다 훨씬 중요합니다. 채널의 현재 상태를 읽을 수 없는 시스템에는 두 가지 선택만 있습니다. 추측하거나, 추측할 수 없다고 말하는 것입니다. “아마 아직 비어 있을 것”이라는 방향으로 추측하는 것이야말로 방이 두 번 팔리는 전형적인 이유입니다. 추측을 거부하는 것, 그것이 “대체로 맞는” 시스템과 “만실일 때 진짜로 믿을 수 있는” 시스템의 차이입니다.