2017-02-14 18 views
1

У нас есть приложение C#, использующее ADO.NET и SQL-сервер с уровнем изоляции транзакций SNAPSHOT. Это «как есть» и, к сожалению, не может быть изменено.Вызов связанного сервера завершается после установки моментального снимка

Теперь нам нужно вставить материал на связанном сервере.

Мы выполняем следующий код (уменьшенный для иллюстрации проблемы):

// Create a snapshot Transaction and close the connection 
using (var con = new SqlConnection(myConStr)) 
{ 
    con.BeginTransaction(TransactionLevel.Snapshot); 
} 

// do something with a linked server 
using (var con = new SqlConnection(myConStr)) 
{ 
    using (var cmd = con.CreateCommand() 
    { 
    cmd.CommandText = "insert into LinkedServer.SomeDb..Table ..."; 
    cmd.ExecuteNonQuery(); 
    } 
} 

Получим может исключение при попытке вставить что-то в связанном сервер

«Удаленный доступ не поддерживается для сделки уровень изоляции «SNAPSHOT» '

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

Выполнение работы в SSMS с использованием простого SQL, похоже, сработает.

Что нам не хватает? Есть ли правильный способ сделать это?

Спасибо за любые подсказки в правильном направлении.

ответ

0

Секрет для понимания проблемы - это «объединение пулов», которое выполняется ADO.NET в фоновом режиме. Фактическое соединение фактически установлено на SNAPSHOT.

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

Решение заключается в том, чтобы явно установить уровень изоляции транзакций на что-то еще сразу после открытия соединения.

using (var con = new SqlConnection(myConStr)) 
{ 
    using (var cmd = con.CreateCommand() 
    { 
    cmd.CommandText = "set transaction isolation Level read committed"; 
    cmd.ExecuteNonQuery(); 
    } 

    using (var cmd = con.CreateCommand() 
    { 
    cmd.CommandText = "insert into LinkedServer.SomeDb..Table ..."; 
    cmd.ExecuteNonQuery(); 
    } 
}