Транзакции SQL Server - вся БД заблокирована? - PullRequest
1 голос
/ 05 октября 2010

У меня проблема с конкретной установкой клиента SQL Server 2008. Я написал код ниже, чтобы смоделировать проблему, которая происходит в более сложной системе. Открыты два соединения (каждое с собственной транзакцией), и каждое соединение изменяет таблицу. Модифицированные таблицы не связаны друг с другом. На платформе разработки и других существующих клиентских установках код работает нормально. Только у одного конкретного клиента возникает проблема, связанная с зависанием второго обновления во вложенной транзакции. Я мог бы обойти эту проблему, переместив первое обновление после фиксации вложенной транзакции.

Я предполагаю, что в этой конкретной установке БД настроена на блокировку всей БД при запуске транзакции. Но использование DBCC useroptions приводит к очень похожему выводу в системах, где работает код, и этот.

Как я могу определить, что здесь не так?

Вот вывод DBCC useroptions из проблемной БД (SQL Server 2008) и мой упрощенный тестовый код:

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

1 Ответ

0 голосов

А почему вы используете "" Provider = SQLOLEDB.1 "для доступа к MS SQL Server?
И почему вы делаете коммит вместо того, чтобы закрывать и утилизировать?

Я могу только догадываться, как упомянутый BusinessCasesHelper, DbAccessFactory и т. Д. Реализованы.
Но ваш вопрос подразумевает, что вы рассматриваете вашу транзакцию открытия фрагмента внутри другой транзакции в том же контексте (то есть для одного соединения), в то время как я вижу, что они, вероятно, открывают два соединения, которые не удаляются..

...