Postgres Professional corporate blog
PostgreSQL
SQL
Comments 15
0
Правило согласованности может звучать так: перевод никогда не меняет общей суммы денег на счетах (такое правило довольно трудно записать на SQL в виде ограничения целостности, так что оно существует на уровне приложения и невидимо для СУБД)


Это не совсем так. Точнее совсем не так. Просто оно будет записано не в виде ограничения (CONSTRAINT), а в виде схемы данных, где сумма фигурирует один раз и к ней так или иначе «подвязаны» два счёта. Такой, классический «транзакционный» (не в смысле СУБД, а в смысле бухгалтерского учёта) вариант. Правда при такой схеме остаток (сальдо) по счёту не хранится, а требует вычисления каждый раз, когда он потребуется.
+2
Оно ж по-разному бывает. Если мы про бухучет, то наверное да, можно все на полупроводках аккуратно устроить. Но в буржуйских системах (OeBS как пример) в одной бухгалтерской транзакции может быть больше двух счетов — и опять получаем ту же самую проблему.
А в статье пример игрушечный, специально упрощенный. Но на нем все довольно хорошо видно.
+1
Я прекрасно всё понимаю: и про игрушечность примера и про разницу между итальянским и англо-саксонским конто (там, кстати, может быть ещё веселее, когда по разным счетам суммы ещё и в разных валютах — сам такое делал :)). Просто начал читать и как-то резануло. Потом втянулся :)
+3
И да, спасибо за статью! Нечастый пример того, как важные, но довольно сложные вещи, объясняются простым и понятным языком. Жду продолжения!
0
Пользовательские блокировки.
Последнее средство — вручную установить исключительную блокировку или на все нужные строки (SELECT FOR UPDATE), или вообще на всю таблицу (LOCK TABLE). Это всегда работает, но сводит на нет преимущества многоверсионности: вместо одновременного выполнения часть операций будет выполняться последовательно.


Не совсем согласен.
Ето минимальное зло. При правильном SELECT мы блокируем только нужние записи.(для примера одного клиента) И операции по другим клиентам проходят паралельно. Но следует учитивать что для всех изменений в даной таблице нужно предварительно использовать
SELECT FOR UPDATE в идеале использовать одну сторедж процедуру.
P.S. Хорошая статтья, На жаль многие разработчики не хотят вникать в такие детали БД.
+1
Когда минимальное, а когда и максимальное.
По сути, выполняя заранее SELECT FOR UPDATE для изменяемых строк, вы эмулируете блокировочный протокол поверх изоляции на основе снимков. Иногда это просто не нужно, иногда это ок, а иногда это вообще не спасает. It depends.
0

Превосходно!
Прошу вас, не останавливайтесь, пишите ещё!

0
Спасибо, отлично разложили всё с примерами
Скину коллегам )
0
Егор, спасибо! Ваши статьи (в частности цикл статей про индексы) читаю и перечитываю много раз, очень рад новой серии статей, очень жду продолжения

В PostgreSQL достаточно средств, чтобы одним SQL-оператором решать сложные задачи. Отметим общие табличные выражения (CTE), в которых в том числе можно использовать операторы INSERT/UPDATE/DELETE, а также оператор INSERT ON CONFLICT, который реализует логику «вставить, а если строка уже есть, то обновить» в одном операторе.


Существует еще конструкция CASE WHEN THEN END, но почему то я очень давно не встречал ее упоминания в статьях (а статей разных читаю много). Я использую периодически эту конструкцию. Почему ее не упоминают? Быть может у нее есть какой-то существенный недостаток?
0

Владимир, спасибо на добром слове.
Недостатков у CASE я не вижу (ну, кроме многословности), прекрасная и полезная конструкция. Я ее использую совершенно автоматически; наверное, потому и не упоминают — вроде как очевидная вещь. Но в любом учебнике по SQL она есть, например в этом.

Only those users with full accounts are able to leave comments. , please.