Базы данных / Внезапно dotNET / CSharp
Сегодня о TransactionScope, уровне изоляции транзакций Serializable и дырявых абстракциях.
Вообще говоря, я раньше много раз сталкивался с распределёнными транзакциями. В какой-то момент я окончательно сформировал своё мнение по этой теме. Получилось что-то вроде: “хватит, я не буду их использовать вообще, разве что в ход со стороны оппонента пойдут огнестрельное оружие и прочие нечестные аргументы”.
По этой причине моё знакомство с TransactionScope свелось к его использованию в интеграционных тестах (без распределённой составляющей, просто для удобного отката транзакций) и редким спорам с коллегами. Но сегодня, внезапно…
Вообще говоря, в появлении этого текста на свет основная заслуга Макса (@force_net).
С ним сегодня сначала говорили про Snapshot Isolation,
потом перешли на TransactionScope. И говорит Макс — “там ведь Serializable по умолчанию”.
Я говорю — “да ладно, нелогично же — без него Read Committed по умолчанию”. Так, слово за слово, решили проверить.
На случай, если вы мало сталкивались с БД, про уровни изоляции есть вполне сносная, хотя не всем с первого раза понятная документация. Поэтому лучше дам ссылку на общее описание от википедии.
Если вкратце, применимость Serializable в web-приложениях не очень высокая — слишком много блокировок. Когда мы с Максом обсуждали эти особенности,
он привёл пример “то есть если один заказывает билеты на фильм, то блокируются на всякий случай все места, а второй будет ждать…”
“… пока фильм не выложат на торрентах выйдет на DVD”, продолжил я :)
Постараюсь чуть позже написать более подробную статью на тему уровней изоляции.
Как я уже говорил, TransactionScope пользовался давно и редко. Поэтому я несколько удивился, увидев подтверждение упомянутому феномену. Сказал я Максу что-то вроде — “с чего-бы высокомудрые архитекторы и разработчики такой нетрадиционный способ обратной совместимости выбрали?”.
А он в меня ссылкой кидает. Ладно, теперь понятны хотя бы предпосылки этого не самого логичного решения — предпочли выбрать поведение по умолчанию как в MS DTC, а не как в MS SQL и System.Data.SqlClient. Но, чёрт возьми, почему я не вижу рядом с названием класса слов “по умолчанию использует уровень изоляции Serializable” большими красными буквами? В документации класса вообще Serializable не упомянули :(
Если вы подсели на “синтаксическое сладкое”, любите async/await (предпочитая не погружаться в детали его работы) и используете TransactionScope из коробки в production — ваше дело. Я больше скажу, даже MS DTC вы можете использовать из приложения в ASP.NET. Да хоть мигающий фиолетовый текст на жёлтом фоне. Кто я такой, чтобы вам указывать? :)
Однако, подумайте над переопределением уровня изоляции транзакций для TransactionScope. Разумеется, я согласен, что для каких-то решений Serializable будет правильным выбором. Главное, чтобы выбор был осознанным…
Базы данных / Внезапно dotNET / CSharp