Стратегии, чтобы избежать эскалации транзакций в System.Transactions - PullRequest
7 голосов
/ 27 декабря 2008

Итак, основываясь на ответе на мой предыдущий вопрос , транзакции do повышаются от LTM до DTC, если во время транзакции открыто несколько соединений, даже если все соединения все имеют одинаковую строку подключения.

Итак, мой следующий вопрос: какие стратегии можно использовать, чтобы избежать этой "функции"? Мне кажется, что, основываясь на использовании ресурсов, я хочу убедиться, что LTM используется в максимально возможной степени. Единственный способ сделать это на должном объектно-ориентированном уровне бизнес-логики - это создать объект статического соединения на уровне запроса на уровне доступа к данным и делиться этим между вызовами до тех пор, пока запрос не будет завершен (здесь подразумевается знание). заключается в том, что сущности бизнес-объекта являются незаметными и не знают, в каком порядке они будут вызываться, кроме того, тот факт, что не нужно создавать пузыри для объекта соединения до уровня бизнес-объекта, поскольку это будет подробностями реализации хранилища данных кровотечение в другой слой).

У кого-нибудь еще есть идеи, которые не полностью разрушают инкапсуляцию слоев n-уровневой системы?

Ответы [ 4 ]

2 голосов
/ 27 декабря 2008

Я использовал класс TransactionHelper, обновляющий все команды в TableAdapter для замены соединения и транзакции на те из TableAdapter, который инициирует транзакцию. Вы можете найти некоторый код, который делает это , который вы можете адаптировать по мере необходимости, в блоге Скотта Лэнфорда, CodeExperiment . У Райана Уитакера есть подобный подход .

Обратите внимание, что поскольку я перешел на использование LINQToSQL, у меня больше нет этой проблемы. Вы можете рассмотреть возможность использования LINQToSQL или nHibernate в качестве альтернативного решения. Либо будет иметь хорошую поддержку для локальных транзакций.

0 голосов
/ 11 января 2009

Как заявил Каспер, избегание DTC может быть преждевременным, хотя это значительный вес. Вы можете реализовать свои соединения, используя статические фабрики, чтобы просто возвращать новые объекты, а затем, если вы решите, что у вас есть проблема, вы можете реализовать механизм, который может хранить транзакции в TLS (или httpcontext, если вы в ASP). И не нужно менять какой-либо код.

Этот вопрос фактически был задан и получен ответ, но я не могу найти его, когда обновлю.

0 голосов
/ 11 января 2009

Я должен спросить, в чем причина того, что мы так старались избежать DTC? В этом или предыдущем ответе нет упоминания о том, почему, и возникает впечатление, что вы можете страдать синдромом преждевременной оптимизации.

0 голосов
/ 27 декабря 2008

Я бы порекомендовал написать класс-оболочку для управления соединениями, транзакциями, объектами команд, вот и все, что связано с БД. Это своего рода очень легкий nHibernate. Этот класс будет предоставлять методы для executeStatement (...), executeQuery (...), addParameter (...), startTransaction (...) и т. Д.

При запуске транзакции вы можете предоставить некоторый (при необходимости уникальный) идентификатор, к которому вы могли бы привязать все последующие запросы, относящиеся к одной и той же транзакции. Затем этот класс-обертка будет содержать статическое сопоставление, с которой выполняется транзакция, с каким соединением, и будет автоматически использовать правильное или создавать новое при необходимости.

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

  • легко регистрировать все операторы для отладки, тестирования производительности
  • логика автоматического повтора при блокировке / проблемах с сетью
  • более простой переключатель поставщика БД
  • в основном некоторые вещи, которые вы получаете с помощью сред персистентности, таких как nHibernate, но более легкие и не такие сложные
...