Когда транзакции подводят

Вспомнилось тут мне лишнее подтверждение моей теории о том, что типичное решение работает типично хреновым образом. Сегодня я расскажу как легко на почти ровном месте отгрести от ms sql.


Транзакции

Итак, у нас есть концепция транзакций. Также большинство бд позволяют параллельное исполнение транзакций. Из-за этого возникают всякие типичные для параллельного программирования косяки. А также не очень типичные косяки из-за возможности отката транзакций.

Изоляция

Чтобы эти косяки решать вводят концепцию уровней изоляции. Каждый уровень избавляет тебя от все большего количества косяков, но обходится как минимум резкими падениями производительности из-за того, что приходится делать локи.

Локи

Чтобы решить эту проблему вводят несколько разновидностей локов и механизм автоповышения уровня лока. Но это приводит к дедлокам на ровном месте, ибо более высокий лок захватывает больше несвязанных с транзакцией ресурсов. Это как раз пример, когда вы написали все правильно, но вас подставляет то, что технология нижележащего уровня — говно.

А дальше

Как вы думаете, а что же можно с этим сделать дальше? А дальше вы можете пойти нахуй, если вас что-то не устраивает. Я вас поддержать в этом путешествии не могу, потому что раньше сходил, а количество путевок ограничено.

А почему? А просто потому что на третий уровень гениальности тимлида индусов не хватило. А продукт вам продали раньше, чем вы поняли, какой же вы неудачник.


Задачка

Сейчас я вам сформулирую задачу: нужно создать порядка нескольких тысяч строк за оптимальное время транзакционно. Потому что бизнес захотел одну фичу определенным образом, и сделать это можно только так.

Хорошо, ну ладно. А давайте напишем в этом месте транзакционность руками, раз стандартный механизм нам не подходит. Для начала нужно выбрать тот уровень изоляции, который не использует локи.

Есть такой. Называется read committed snapshot isolation, работает через mvcc. Но как вы могли догадаться, есть как минимум одна проблема. Это не isolation level, а настройка целой бд. +14 байт к каждой строке в бд. Также дополнительные накладные расходы прямо в tempdb. И в интернетиках написано, что при этом может поменяться то, как исполняется код.

Увы, нереально это включить на проекте в пару лет. Не, вообще, честно говоря я не знаю. Просто я об этой ерунде либо первый раз прочитал во время написания этого поста, либо эта идея очень быстро слилась. Впрочем, не думаю, что мне бы разрешили это сделать.


А может есть другой уровень изоляции? Да, этот уровень изоляции называется Chaos. Как его включить в ms sql вкратце описано здесь: state of chaos isolation level in ms sql server.

Но есть одна проблема. И дальше маленький спойлер. Кто угадает?



P.S: поэтому в данном случае надо писать свои транзакции поверх стандартных транзакций и вставлять данные порционно примерно по сто строк за транзакцию. Что не помогает производительности, но хотя-бы решает задачу без укладки целого сайта на лопатки.

P.P.S: некоторые бд вообще начисто отказались от идеи давать возможность исполнять несколько транзакций параллельно. К примеру, datomic.

Like what you read? Give Viktor Love a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.