7
votes

Comment activer les transactions imbriquées avec Ado.net et SQL Server?

J'ai une question similaire à Comment vérifier si vous êtes dans une transaction . Au lieu de vérifier, comment puis-je autoriser des transactions imbriquées?

J'utilise la base de données Microsoft SQL Server avec Ado.net. J'ai vu des exemples à l'aide de T-SQL et des exemples de démarrage des transactions en utilisant le début et l'utilisation de noms de transaction. Lorsque vous appelez Connection.begintransaction, j'appelle une autre fonction dans la même connexion et cela appelle à nouveau Begintransaction qui me donne l'exception: xxx

Il apparaît de nombreuses variantes Microsoft le permettent, mais Je ne peux pas comprendre comment le faire avec mon fichier .MDF.

Comment puis-je autoriser des transactions imbriquées avec une base de données Microsoft SQL Server à l'aide de C # et ADO.net?


0 commentaires

3 Réponses :


8
votes

SQL Server dans son ensemble ne prend pas en charge les transactions imbriquées. Dans T-SQL, vous pouvez émettre un Commencer le Tran à l'intérieur d'un Begin TRAN Mais ceci est juste pour la commodité. Ce n'est que la transaction extérieure qui compte. Le client .NET pour SQL Server ( sqlconnection ) ne vous permet pas même de le faire et jette cette exception lorsque vous essayez.


5 commentaires

Mon hôte dit qu'ils offrent "Microsoft SQL 2008". Est ce t-SQL? Sinon d'où vient T-SQL? Je veux seulement que la transaction externe compte. "Microsoft SQL 2008 'ne permet-il pas cela? (Peut-être de la configurer de ne pas lancer une exception?)


T-SQL est la variante de Microsoft de la norme SQL qui fonctionne dans toutes les versions de SQL Server. Si vous souhaitez éviter cette exception, évitez simplement d'appeler Begintransaction Avant de commettraliser ou de renvoyer une transaction antérieure - vous ne pouvez pas être une transaction si une transaction antérieure est toujours en attente. Je vous recommande de jeter un oeil à l'aide de transactionsCope ( msdn.microsoft.com/en-us/library/... ) au lieu d'essayer de les gérer vous-même.


hmm, ce n'est pas la même chose. Ce code a été utilisé avec SQLite et je ne suis pas sûr si cela est pris en charge (cela pourrait être car il semble que cela semble supporter tout ADO.NET). Mais cela semble étrange, si T-SQL est dans toutes les versions de SQL Server, je ne dois pas que cela ne soit pas autorisé? Qu'une fonctionnalité fera ma vie plus facile. Même si seulement une seule fonction qui l'utilise (je suppose que je pourrais la détruire depuis sa seule sur laquelle une seule connexion est utilisée jusqu'à ce que.)


T-SQL est la dialecte de langue SQL de SQL Server. SQLConnection Problèmes Commandes à SQL Server dans T-SQL, mais même si T-SQL vous permet de (superficiellement) Nest Transactions, SQLConnection fait pas le permet. Vous pouvez émettre un Commencer la commande Commandez votre site via un SQLCOMMAND, mais vous seriez ensuite contourner la prise en charge de tous.


Hmm. Bon à savoir. Merci, il semble que le moyen le plus simple de résoudre est de tuer la transaction externe car elle n'est utilisée qu'une seule fois et était là pour obtenir une meilleure performance en SQLite (sa seule fonctionne une fois que ce n'est donc pas une grande partie d'un boost).



0
votes
SqlConnection conn = new SqlConnection(@"Data Source=test;Initial Catalog=test;User ID=usr;Password=pass");
conn.Open();
var com = conn.CreateCommand();

com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "BEGIN TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "INSERT INTO testTable (ParamName,ParamValue) values ('test','test');";
com.ExecuteNonQuery();
com.CommandText = "COMMIT TRANSACTION";
com.ExecuteNonQuery();
com.CommandText = "ROlLBACK TRANSACTION";
com.ExecuteNonQuery();

com.CommandText = "SELECT COUNT(*) FROM testTable ";

MessageBox.Show(string.Format("Found {0} rows.", com.ExecuteScalar()));

1 commentaires

Cette réponse pourrait bénéficier de quelques commentaires sur ce que vous avez découvert en le gérant.



4
votes

Il s'agit d'une idée fausse commune que SQL Server prend en charge les transactions imbriquées. Ce ne est pas. Ouverture de multiples transactions, puis appeler commettre ne fait absolument rien. Vous pouvez facilement écrire du test SQL pour essayer ceci vous-même. La seule option ici pour émuler une transaction imbriquée consiste à utiliser les points de sauvegarde.

Je devrais ajouter que la seule chose qui compte est quand @@ Tran_Count atteint zéro est le point sur lequel seule la transaction extérieure sera commise.


0 commentaires