J'ai un problème sur l'installation spécifique du client SQL Server 2008. J'ai écrit le code ci-dessous pour simuler le problème qui se produit dans un système plus complexe. Deux connexions (chacune avec sa propre transaction) sont ouvertes et chaque connexion modifie une table. Les tables modifiées ne sont pas liées entre elles. Sur la plate-forme de développement et les autres installations client existantes, le code fonctionne correctement. Seulement chez un client spécifique nous avons un problème que la deuxième mise à jour dans la transaction imbriquée se bloque. Je pourrais faire une solution de contournement en déplaçant la première mise à jour après la validation de la transaction imbriquée.Transactions SQL Server - ensemble db verrouillé?
Je suppose que dans cette installation spécifique, la base de données est configurée pour verrouiller la totalité de la base de données lorsqu'une transaction est démarrée. Mais l'utilisation de DBCC useroptions
donne des résultats très similaires sur les systèmes où le code fonctionne et celui-ci.
Comment puis-je identifier ce qui ne va pas ici?
est ici DBCC useroptions
sortie de la problématique DB (SQL Server 2008) et mon code d'essai simplifié:
textsize 2147483647
language Deutsch
dateformat dmy
datefirst 1
lock_timeout -1
quoted_identifier SET
arithabort SET
ansi_null_dflt_on SET
ansi_warnings SET
ansi_padding SET
ansi_nulls SET
concat_null_yields_null SET
isolation level read committed
DbCommand command1 =null, command2 = null;
try
{
const string cs = "Provider=SQLOLEDB.1;...";
// open command and a transaction with default isolation level
command1 = DbAccessFactory.CreateInitialzedCommand("System.Data.OleDb", cs, true);
// select something
command1.CommandText = "select * from plannerOrderHeaders where ...";
DataSet ds = BusinessCasesHelper.Fill(command1, null, "plannerOrderHeaders");
// make some changes in the table
...
// update the table in DB
BusinessCasesHelper.Update(command1, ds, true);
// open command and a transaction with default isolation level on the same CS as command1
command2 = DbAccessFactory.CreateInitialzedCommand("System.Data.OleDb", cs, true);
// select something
command2.CommandText = "select * from mdOmOrders where ...";
ds = BusinessCasesHelper.Fill(command2, null, "mdOmOrders");
// make some changes
...
// update the db
BusinessCasesHelper.Update(command2, ds, true);
command2.Transaction.Commit();
cmd2Commited = true;
command1.Transaction.Commit();
}
catch (Exception e) {...}
Désolé, j'ai omis de fermer dans cet exemple parce que je voulais juste simuler le comportement dans une petite application de console. OleDb est utilisé en raison de la portabilité. MS SQL n'est pas la seule option ici. La validation sera effectuée car des transactions sont ouvertes avec chaque connexion. Pour présenter la situation en pseudocode je le décrirais comme ceci:
conn1.open – Vladimir
Désolé, j'ai omis de fermer dans cet exemple parce que je voulais juste simuler le comportement dans une petite application de console. OleDb est utilisé en raison de la portabilité. La validation sera effectuée car des transactions sont ouvertes avec chaque connexion. En utilisant le pseudocode je le décrirais comme ceci: conn1.open; txn1.start; conn1.performUpdate (tab1); conn2.open; txn2.start; conn2.performUpdate (tab2); txn2.commit conn2.close txn1.commit conn1.close si je propose conn1.performUpdate (tab1); après txn2.commit tout va bien. En réalité, il s'agit d'un système de plug-in où la deuxième connexion est ouverte par un plugin. – Vladimir
Aujourd'hui, j'ai enquêté un peu plus loin. J'ai essayé d'ouvrir trasnactions avec toutes les variantes possibles de System.Data.IsolationLevel. N'a pas aidé. Seulement ne pas commencer une transaction du tout aidé, mais ce n'est pas acceptable dans le système productif. – Vladimir