#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, а затем передавать его по мере необходимости.