views:

47

answers:

1

Hi, I have a problem on specific SQL Server 2008 customer installation. I wrote the code below to simulate the problem which happens in more complex system. There are two connections (each one with own transaction) opened and each connection modifies a table. Modified tables do not relate to each other. On development platform and other existing customer installations the code works fine. Only at one specific customer we have a problem that the second update in nested transaction hangs. I could make a workaround by moving the first update after commit of nested transaction.

I assume in that specific installation the db is configured to lock down the whole db when a transaction is started. But using DBCC useroptions results in very similar output on systems where the code works and this one.

How can I identify what's wrong here ?

Here's DBCC useroptions output from the problematic DB (SQL Server 2008) and my simplified test code:

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

And why do you use ""Provider=SQLOLEDB.1" to access MS SQL Server?
And why do you commit instead of closing and disposing?

I can only guess how the mentioned BusinessCasesHelper, DbAccessFactory, etc. are implemented.
But your question implies that your consider your snippet opening transaction inside another transaction in the same context (i.e. on one connection) while I see that they are probably opening two connections which are not being disposed.

vgv8
Sorry, I ommited closing in this sample because I just wanted simulate the behaviour in a small console app. OleDb is used bacause of portability. MS SQL is not the only option here. Commit will be done because there are transactions opened with each connection. To present the situation in pseudocode I would describe it like this:<br>conn1.open
Vladimir
Sorry, I omited closing in this sample because I just wanted simulate the behaviour in a small console app. OleDb is used bacause of portability. Commit will be done because there are transactions opened with each connection. Using pseudocode I would describe it like this:conn1.open;txn1.start;conn1.performUpdate(tab1);conn2.open;txn2.start;conn2.performUpdate(tab2);txn2.commitconn2.closetxn1.commitconn1.closeif I move conn1.performUpdate(tab1); after txn2.commit everything worx fine.In reality this is a plugin system where the second connection is opened by a plugin.
Vladimir
Today I investigated a little bit further. I tried to open trasnactions with all possible variants of System.Data.IsolationLevel. Didn't help. Only not starting a transaction at all helped, but this is not acceptable in productive system.
Vladimir
Now I found the reason. This one customer has some additional functionality part of which is an update trigger on first table. The trigger modifies the second table. This of course clarifies the situation. Blame on me ;o)
Vladimir