2010-10-05 10 views
1

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) {...} 

Répondre

0

Et pourquoi utilisez-vous "" Provider = SQLOLEDB.1" pour accéder à MS SQL Server
? et pourquoi avez-vous commettez au lieu de fermer et disposer?

Je ne peux que deviner comment le BusinessCasesHelper mentionné, DbAccessFactory, etc. sont mis en œuvre.
Mais votre question implique que votre transaction considérer votre ouverture dans un autre extrait transaction dans le même contexte (c.-à-d. sur une connexion) alors que je vois qu'ils ouvrent probablement deux connexions qui ne sont pas disposées.

+0

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

+0

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

+0

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