Область транзакций с объединением в Linq2SQL

#c# #sql-server-2005 #linq-to-sql #transactionscope

#c# #sql-server-2005 #linq-to-sql #область транзакций

Вопрос:

Если для пула в строке подключения установлено значение true, следующий код работает нормально. При включении происходит сбой с сообщением: «MSDC недоступен».

Это просто чистая удача, что оба DataContext выбирают одно и то же соединение из пула при включенном объединении, или есть какая-то координация, выполняемая TransactionScope ?

 using(var scope = new TransactionScope())
{
    using(var db = new DataContext(connectionString))
    {
        //Do stuff
    }
    using(var db = new DataContext(connectionString))
    {
        //Do stuff
    }
    scope.Complete();
}
  

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

Комментарии:

1. В чем причина, по которой вы используете два datacontexts одного и того же типа и одну и ту же строку подключения? Почему бы просто не использовать один Datacontext?

2. @Pleunфункция на уровне бизнес-логики вызывает множество функций на уровне доступа к данным, каждая функция создает свой собственный контекст данных.

3. Итак, первый // Do stuff — это функция DataAccessLayer, а второй // Do stuff — это вторая функция? Тем не менее, они могут использовать один и тот же datacontext, не так ли?

4. @Pleunэто правильно. Если они собираются использовать один и тот же контекст, в нем должно быть какое-то управление временем жизни или синхронизация, я не могу просто создать его и поместить в переменную в классе DAL, поскольку я не могу быть уверен, как долго и с помощью каких других потоков осуществляется доступ в данный момент.

5. Ну, управление временем жизни и datacontext не сочетаются друг с другом. Это должно быть логической единицей работы и недолговечным. Вы используете winforms?

Ответ №1:

Здесь вам повезло, потому что обе ваши строки подключения совпадают, поэтому вы получаете одно и то же объединенное соединение, когда объединение в пул включено. Однако результаты будут неопределенными, если имеется несколько одновременных обращений к соединениям с этой строкой подключения, потому что вы можете не получить такое же объединенное соединение во втором экземпляре DataContext.

Если вам нужно создать два объекта DataContext в рамках одной транзакции, тогда вам нужно будет использовать DTC. Если вы не можете использовать DTC, то вам нужно будет найти способ использовать только один объект DataContext в транзакции.

Комментарии:

1. Я использую одну и ту же транзакцию для обоих DataContext в моем примере, и она отлично работает без DTC, пока включено объединение. Но как я могу быть уверен, что из пула выбрано то же соединение? Не много ли подключений (использующих одну и ту же строку подключения) в пуле или только одно?

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

3. Теперь можно было бы гарантировать, что вы получаете одно и то же соединение каждый раз, ограничив размер пула соединений до 1, добавив «Максимальный размер пула = 1» в строку подключения. Однако это не будет хорошо масштабироваться, и я бы не рекомендовал это делать.

4. Спасибо за ответ. Как бы вы предложили решить подобную проблему? Явная отправка в том же соединении с DataContext?

5. Я бы сделал это, или вы также могли бы попробовать провести рефакторинг, чтобы создать только один объект DataContext, а затем передавать его по мере необходимости.