Возникает ли эскалация распределенных транзакций, если одна из баз данных ТОЛЬКО ЧИТАЕТСЯ? - PullRequest
0 голосов
/ 14 января 2010

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

Источник находится на отдельном сервере, чем пункт назначения. Оба MS MS 2008. Мы обращаемся к источнику, используя Linq2SQL, и к месту назначения, используя пользовательский уровень данных. Мы никогда не модифицируем исходную БД (хотя в настоящее время мы не восстанавливаем ее только для чтения). Однако прямо сейчас, когда мы запускаем импорт в TransactionScope, вся транзакция переводится в DTC, потому что мы получаем доступ к двум БД на отдельных серверах.

Если бы мы сделали исходную БД доступной только для чтения, она все равно бы это делала?

Любые другие предложения о том, как избежать продвижения DTC в этом сценарии?

Последующие вопросы к ответу Ремуса (еще раз спасибо):

Продолжение № 1: Моя процедура импорта структурирована так, что она импортирует записи из источника и создает новые записи в месте назначения. Как это:

using(var scope = new TransactionScope())
{
   // read some from source db using Linq2Sql
   // transform source info
   // update destination

   // read some more from source db using Linq2Sql
   // transform source info
   // update destination

}

Вы говорите, что окружаете биты Linq2Sql в TransactionScope с помощью RequNew? Или, я полагаю, если мне действительно безразличны транзакции в источнике, я мог бы использовать TransactionScope с Suppress для включения этого соединения в какую-либо транзакцию, верно?

Продолжение № 2:

Когда вы говорите «открыть второе соединение, даже к той же базе данных» - я прочитал несколько вариантов этого:

  1. "второе соединение" == второй экземпляр объекта Соединения, даже если это точно такая же строка соединения
  2. «второе подключение» == подключение к отдельному диспетчеру ресурсов и в SQL2005 и до этого означает то же, что и выше 1, но в SQL2008 это означает отдельный экземпляр (т. Е. Два БД в одном экземпляре не повышаются)

1 Ответ

2 голосов
/ 14 января 2010

В момент открытия второго соединения ADO.Net в области транзакции оба соединения будут переведены в DTC. даже если это новое соединение с той же БД, не имеет значения. Доступность базы данных только для чтения также не имеет к этому никакого отношения и не может иметь к этому никакого отношения. Во-первых, соединения не зависят от базы данных, поскольку они могут изменить базу данных после открытия. Во-вторых, база данных только для чтения может выполнять много операций записи (например, может вызывать readonlydb.dbo.myProcedure, и внутри процедуры я могу обновить writabledb.dbo.table).

Если вы хотите избежать DTC, вы должны использовать разные области транзакций между двумя уровнями доступа (т. Е. Создать новую область с помощью RequireNew).

Обновление

Если возможно выполнить чтение вне области видимости, было бы идеально:

// read some from source db using Linq2Sql 
// read some more from source db using Linq2Sql 
using(var scope = new TransactionScope()) 
{ 
   // transform source info 
   // update destination 

   // transform source info 
   // update destination 
} 

Я понимаю, что это крайне маловероятно, поскольку, вероятно, второй набор операций чтения обычно зависит от результата первого преобразования / обновления. Таким образом, вы лучше подавите объем при чтении:

using(var scope = new TransactionScope()) 
{ 
   using(var nada= new TransactionScope(TransactionScopeOption.Supress))
   {
       // read some from source db using Linq2Sql 
       // transform source info 
   }
   // update destination 

   using(var nada= new TransactionScope(TransactionScopeOption.Supress))
   {
       // read some more from source db using Linq2Sql
       // transform source info 
   } 
   // update destination 
} 

Кстати, я предполагаю, что «чтение некоторых данных с использованием linq» означает, что вы фактически перечисляете запрос, а не просто создаете выражение запроса и используете выражение позже. Я не знаю точно, как область транзакции взаимодействует с выражением запроса, но я предполагаю, что область применяется к выполнению запроса, а не к объявлению.

...