2017-02-14 1 views
1

Nous avons une application C# utilisant ADO.NET et un serveur SQL avec un niveau d'isolement de transaction SNAPSHOT. Ceci est 'tel quel' et ne peut malheureusement pas être modifié.L'appel d'un serveur lié échoue après l'élimination d'une connexion d'instantané

Maintenant, nous avons besoin d'insérer des trucs sur un serveur lié.

Nous exécutons le code suivant (réduit pour illustrer le problème):

// 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(); 
    } 
} 

Nous obtenons une exception est lorsque vous essayez d'insérer quelque chose dans le serveur lié

« accès à distance ne sont pas pris en charge pour la transaction niveau d'isolement "SNAPSHOT" '

Je me demande pourquoi ce n'est pas possible: Nous ouvrons la connexion, nous assurons qu'elle est éliminée (effaçant toutes les transactions, je suppose) et utilisons une deuxième connexion pour l'appel du serveur lié. L'exécution de la tâche dans SSMS à l'aide de SQL simple semble fonctionner.

Qu'est-ce qui manque? Y a-t-il une bonne façon de le faire?

Merci pour tous les conseils dans la bonne direction.

Répondre

0

Le secret pour comprendre le problème est le «regroupement de connexions» qui est effectué par ADO.NET en arrière-plan. La connexion réelle est définie sur SNAPSHOT.

Dans la deuxième partie de l'exemple de code, cette connexion est simplement réutilisée, ce qui signifie qu'elle est toujours en «mode instantané».

La solution consiste à définir explicitement le niveau d'isolation des transactions sur autre chose juste après l'ouverture de la connexion.

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(); 
    } 
}