Как выполнить обновления в Entity Framework 3.5 в рамках SqlTransaction - PullRequest
0 голосов
/ 06 октября 2010

Я работаю над плагином, который загружается через IOC из стороннего драйвера данных.Плагин и драйвер данных работают с одной и той же базой данных SQL Server 2005, но плагин фокусируется на небольшом подмножестве таблиц, которые имеют отношения внешнего ключа к таблицам, которыми управляет драйвер данных.

Моя проблема заключается вВ некоторых операциях драйвер данных создает SQLTransaction вокруг вызовов моего плагина, что приводит к сбою моих операций (исключение тайм-аута).Типичный сценарий следует этому пути псевдокода / кода:

DataDriver.InsertEntity(IBusinessObject businessObject)
{
    CreateSqlTransaction();
    AddEntityToEntityTable(businessObject);
    Plugin.PersistAdditionalData(businessObject);
    CommitOrRollbackTransaction();
}

В моем плагине я делаю что-то вроде этого:

Plugin.PersistAdditionalData(IBusinessObject businessObject)
{
    var dbObject = GetObjectFromDatabase(businessObject);  // Via Entity Framework
    var additionalData = CreateAdditionalDataObject(businessObject);

    // Insert data to a table with a foreign key relationship to a table that the
    // data driver has just inserted the business object data to in the current
    // transaction.
    _entityModel.AddToObject_AdditionalData_AssociationSet(additionalData);
    _entityModel.SaveChanges();        
}

Я попытался обернуть мой методв блоке using (TransactionScope) {...}, но не удалось заставить его работать.Однако он переместил ошибку из чтения (GetObjectFromDatabase) в сохранение.

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

1 Ответ

1 голос
/ 10 октября 2010

Это только догадки ...

Драйвер данных использует соединение SQL, отличное от вашего плагина. Таким образом, ваш код выполняется в другой транзакции (или без нее) и конфликтует с незафиксированными изменениями в драйвере данных, что приводит к мертвой блокировке.

Идеи решения:

  • Заставьте ваш код использовать то же соединение, что и драйвер данных. Это потребует, чтобы соединение было каким-то образом предоставлено плагинам. И вам нужен способ, чтобы заставить модель сущностей использовать ее (никогда не работал с моделью сущностей лично для меня). Это было бы самым хорошим решением. Вы автоматически участвуете в транзакции со всеми приятными последствиями, такими как последовательность и тому подобное.
  • Попробуйте убедиться, что оба соединения выполняются в одной транзакции. Это теоретически возможно при использовании System.Transactions. Это также требует адаптации драйвера данных для использования модели System.Transactions. Я сомневаюсь, что эти два соединения увидят, как другие изменится таким образом, так что это, вероятно, не сработает.
  • Не используйте транзакции. Возможно, вы сможете указать серверу базы данных игнорировать транзакции, поэтому вам не нужно вносить изменения в драйвер данных. Это будет работать. Конечно, транзакции были изобретены по причине ...

Я бы пошел за первым. Выясните, как вы можете указать модели сущностей использовать конкретное соединение SQL, а затем попросить разработчиков драйверов данных дать вам это. Это может даже привести к повышению производительности, поскольку требуется меньше подключений.

...