Транзакционное программирование в наши дни является основным продуктом современного развития. Параллелизм и отказоустойчивость критически важны для долговечности приложений, и, правильно, логику транзакций стало легко реализовать. Однако по мере роста приложений кажется, что транзакционный код имеет тенденцию становиться все более и более обременительным для масштабируемости приложения, и когда вы соединяетесь с распределенными транзакциями и зеркалированными наборами данных, проблемы начинают становиться очень сложными. Мне любопытно, в чем, по-видимому, суть в размере данных или сложности приложения, что транзакции часто начинают становиться источником проблем (вызывая тайм-ауты, взаимоблокировки, проблемы с производительностью в критически важном коде и т. д.), Которые труднее исправить, устранить или обходной путь, чем разработка модели данных, которая сама по себе является более отказоустойчивой, или использование других средств для обеспечения целостности данных. Кроме того, какие шаблоны проектирования служат для минимизации этих воздействий или для того, чтобы стандартная транзакционная логика устарела или не стала проблемой?
-
Обновлено: У нас есть несколько ответов разумного качества, но я думаю, что я отправлю ответ сам, чтобы поднять некоторые из вещей, о которых я слышал, чтобы попытаться вдохновить на дополнительное творчество; Большинство получаемых мной ответов - пессимистические взгляды на проблему.
Еще одно важное замечание: не все блокировки являются результатом плохо запрограммированных процедур; иногда есть критически важные операции, которые зависят от аналогичных ресурсов в разных порядках, или сложные соединения в запросах разные, которые наступают друг на друга; это проблема, которая иногда может казаться неизбежной, но я участвовал в переработке рабочих процессов, чтобы упростить порядок выполнения, который с меньшей вероятностью вызовет его.
Я добавил некоторые дополнительные детали к вопросу и даже поместил ответ, более близкий к тому, что я ищу, но, похоже, это могло быть засосано в вихрь SO.


Я думаю, что никакой шаблон проектирования не может решить эту проблему сам по себе. Хороший дизайн базы данных, хорошее программирование процедур магазина и особенно умение делать ваши транзакции короткими, решат большинство проблем. Однако не существует 100% гарантированного способа избежать проблем.
Однако практически во всех случаях, которые я видел за свою карьеру, взаимоблокировки и замедления решались путем исправления хранимых процедур:
Использование общих ресурсов в конечном итоге неверно. Потому что, повторно используя существующую среду, вы создаете все больше и больше возможностей. Просто посмотрите на занятых бобров :) Путь, которым идет Erlang, - это правильный путь для создания отказоустойчивых и легко проверяемых систем.
Но транзакционная память важна для многих широко используемых приложений. Например, если вы консультируетесь с банком с миллионами его клиентов, вы не можете просто скопировать данные ради эффективности.
Я думаю, что монады - это крутая концепция, позволяющая справиться со сложной концепцией изменения состояния.
Если вы говорите здесь об «облачных вычислениях», ответ будет заключаться в локализации каждой транзакции в том месте, где она происходит в облаке.
Нет необходимости в том, чтобы все облако было согласованным, так как это снизит производительность (как вы отметили). Просто отслеживайте, что и где изменилось, и обрабатывайте несколько небольших транзакций по мере того, как изменения распространяются по системе.
Ситуация, когда пользователь A обновляет запись R, а пользователь B на другом конце облака (пока) не видит ее, аналогична ситуации, когда пользователь A еще не внес изменения в текущей среде строгих транзакций. Это может привести к несоответствию в системе с большим количеством обновлений, поэтому системы должны быть спроектированы так, чтобы работать с обновлениями как можно реже - переход к агрегации данных и извлечение агрегатов, как только точное число станет критическим (т.е. от времени записи до времени критического чтения).
Ну, только мой POV. В этом случае сложно представить систему, которая не зависела бы от приложений.
Постарайтесь внести изменения на уровне базы данных, используя как можно меньшее количество инструкций.
Общее правило - блокировать ресурс как можно быстрее. Используя T-SQL, PLSQL, Java на Oracle или любой аналогичный способ, вы можете сократить время, в течение которого каждая транзакция блокирует общий ресурс. Я факт, что транзакции в базе данных оптимизированы с помощью блокировок на уровне строк, многоверсий и других интеллектуальных методов. Если вы можете совершить транзакцию в базе данных, вы сохраните сетевую задержку. Помимо других уровней, таких как ODBC / JDBC / OLEBD.
Иногда программист пытается получить преимущества базы данных (она транзакционная, параллельная, распределенная), но сохраняет кеширование данных. Затем им нужно вручную добавить некоторые функции базы данных.
Один из подходов, о котором я слышал, - это создание модели с версией только для вставки, в которой никогда не происходит никаких обновлений. Во время выбора версия используется для выбора только последних строк. Один недостаток этого подхода, о котором я знаю, заключается в том, что база данных может очень быстро стать довольно большой.
Я также знаю, что в некоторых решениях, таких как FogBugz, не используются принудительные внешние ключи, что, как я считаю, также поможет смягчить некоторые из этих проблем, потому что план запроса SQL может блокировать связанные таблицы во время выборок или обновлений, даже если данные не меняются в их, и если это очень спорная таблица, которая блокируется, это может увеличить вероятность DeadLock или Timeout.
Я мало что знаю об этих подходах, поскольку я никогда их не использовал, поэтому я предполагаю, что у каждого из них есть плюсы и минусы, о которых я не знаю, а также некоторые другие методы, о которых я никогда не слышал.
Я также изучал некоторые материалы из недавний пост Карло Пескио, и, к сожалению, у меня не было достаточно времени, чтобы отдать ему должное, но материал кажется очень интересным.
Вопрос довольно субъективный. Кроме того, он довольно расплывчатый и, вероятно, слишком общий, чтобы получить конкретный ответ. Вы должны попытаться перефразировать это.