теория
Раз сериализуемость спасает от write skew — почему бы не включить её на всю базу и не спать спокойно? Отличный вопрос, и ответ на него отделяет джуна от архитектора.
Достичь «как будто по очереди» можно тремя способами, и у каждого своя цена:
Видишь закономерность? За сильную изоляцию всегда платят пропускной способностью: либо ждём в блокировках, либо откатываем и переделываем. Поэтому серьёзные системы не задирают изоляцию глобально — они включают её точечно, вокруг инвариантов, которые нельзя нарушить: баланс, остаток, лимит. Всё остальное — каталог, история просмотров, лента — прекрасно живёт на слабой изоляции и радуется скорости.
И ещё одно, важное для нас. Помнишь, при выделении платежей мы обошли стороной и её ? Теперь понятно почему: 2PC — это те же блокировки, только растянутые по сети, с координатором, который сам может упасть посреди процесса и подвесить всех участников. За сетью цена сериализуемости взлетает до небес. Дешевле держать денежный инвариант внутри одного сервиса-владельца — и там уже включать сериализуемость локально.
Мораль модуля: деньги требуют сериализуемости ровно там, где ошибка непростительна. Всё остальное переживёт согласованность в конечном счёте — и скажет тебе спасибо за скорость.