Блокировки, вызывающие "Server failed to resume the transaction" с NHibernate и распределенными транзакциями

У нас возникла проблема при использовании NHibernate с распределенными транзакциями.

Рассмотрим следующий фрагмент:

//
// There is already an ambient distributed transaction
//
using(var scope = new TransactionScope()) {
    using(var session = _sessionFactory.OpenSession())
    using(session.BeginTransaction()) {
        using(var cmd = new SqlCommand(_simpleUpdateQuery, (SqlConnection)session.Connection)) {
            cmd.ExecuteNonQuery();
        }

        session.Save(new SomeEntity());
        session.Transaction.Commit();
    }
    scope.Complete();
}

Иногда, когда сервер находится под экстремальной нагрузкой, мы видим следующее:

  1. Запрос, выполняемый с помощью cmd.ExecuteNonQuery, выбирается в качестве жертвы тупика (мы можем видеть это в SQL Profiler), но исключение не поднимается.
  2. session.Save терпит неудачу с сообщением об ошибке, "The operation is not valid for the state of the transaction."
  3. Каждый раз, когда этот код выполняется после этого, session.BeginTransaction терпит неудачу. Первые несколько раз внутреннее исключение меняется (иногда это исключение deadlock, которое должно было возникнуть на шаге 1). В конце концов оно стабилизируется до "Серверу не удалось возобновить транзакцию. Desc:3800000177." или "Новый запрос не может быть запущен, потому что он должен прийти с действительным дескриптором транзакции."

Если оставить приложение в покое, оно в конце концов (через несколько секунд или минут) выйдет из этого состояния.

Почему исключение тупика не сообщается на шаге 1? И если мы не можем решить эту проблему, то как мы можем предотвратить временную неработоспособность нашего приложения?

Проблема была воспроизведена в следующих средах

  • Windows 7 x64 и Windows Server 2003 x86
  • SQL Server 2005 и 2008
  • .NET 4.0 и 3.5
  • NHibernate 3.2, 3.1 и 2.1.2

Я создал тестовое приспособление, которое иногда воспроизводит проблему для нас. Он доступен здесь: http://wikiupload.com/EWJIGAECG9SQDMZ

12
задан jon without an h 17 January 2012 в 20:48
поделиться