Как запустить два контекста Entity Framework внутри TransactionScope без MSDTC?
эта проблема не легко воспроизводима в простом примере здесь, но было интересно, есть ли у кого-нибудь опыт и советы, вот проблема:
- используя Entity Framework
- есть много точек в приложении, где (1) данные записываются в некоторые сущности таблица например клиент, (2) данные записываются в история стол
- и из этих действий используйте Entity Framework, однако они используют разные условиях
- эти действия должны быть как в одна сделка: т. е. если один не пишет, другой не должен писать и т. д.
- Я могу обернуть их трансакционным микроскопом,
такой:
using (TransactionScope txScope = new TransactionScope()) {
...
}
но это дает мне:
координатор распределенных транзакций Microsoft (MSDTC) отключен для сетевые транзакции.
наш администратор базы данных сказал мне это координатор msdtc отключен по выбору и не может быть установлен.
следовательно, я делаю изменения, пытаясь создать свою собственную EntityConnection с MetadataWorkspace с идеей, что каждый контекст будет использовать тот же EntityConnection. Однако это почти невозможно, пытаясь заставить его работать, например, в настоящее время я продолжаю получать вышеуказанную ошибку, хотя теоретически оба контекста используют EntityConnection. Трудно например, понять, где / почему Entity Framework требует MSDTC.
кто-нибудь пошел по этому пути раньше, есть опыт или примеры кода, чтобы поделиться?
3 ответов
Ну, проблема довольно легко.
Если вы используете sql server 2008, у вас не должно быть этой проблемы, потому что у вас есть промотируемая транзакция, и поскольку .NET знает, что вы используете то же хранилище сохраняемости (база данных), он не будет продвигать его в DTC и фиксировать его как локальный. посмотреть в сделке, перспективная с SQL сервера 2008.
насколько я знаю, Oracle работает в своем драйвере для поддержки промотируемых транзакций, но я не знаю состояния, Драйвер MS oracle не поддерживает его. http://www.oracle.com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf
Если вы используете драйвер, который не поддерживает промотируемые транзакции, .NET не может использовать локальную транзакцию, выполняющую два соединения. Вы должны изменить свою архитектуру или убедить администратора базы данных для установки MSDTC.
у меня была аналогичная проблема с SQL 2008, Entity Framework.
у меня было два фреймворка (EF1 и EF2), но с использованием идентичных строк подключения к базе данных sql 2008.
Я получил ошибку MSDTC выше, при использовании вложенных "использований"по обоим. например, код был таким:
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
}
dbContext.Complete();
}
это было не так просто, потому что он был разделен на несколько методов, но это была основная структура "использования".
исправление было только открыть используя одновременно. Нет ошибки MTDSC, нет необходимости открывать распределенные транзакции в БД.
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
}
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
dbContext.Complete();
}
Я думаю, что вам нужно сделать, это заставить ваши контексты совместно использовать одно соединение с базой данных. Затем вы сможете выполнять эти две операции в двух разных контекстах в одной транзакции. Этого можно достичь, передав один объект EntityConnection обоим конструкторам контекста. Конечно, этот подход потребует от вас передать этот объект методам, которые обновляют БД.
У меня недавно блоге о создании области контекста базы данных что облегчит использование нескольких контекстов и транзакций EF.