Должен ли я к явному удалению транзакции после того, как я уже удалил сеанс? - PullRequest
1 голос
/ 08 ноября 2019

Я думаю, что в этом случае нет необходимости (хотя я знаю, что мы можем использовать using как для транзакции, так и для сеанса). Вот код, который мне интересен:

using(var session = _sessionFactory.OpenSession()){
     session.BeginTransaction();
     try {
        //some code
        session.Transaction.Commit();
     } catch(Exception ex){
        session.Transaction.Rollback();
     }
}

Есть ли утечка кода выше? Я знаю, что было бы лучше написать это следующим образом:

using(var session = _sessionFactory.OpenSession()){
     using(var t = session.BeginTransaction()){
       try {
          //some code
          t.Commit();
       } catch(Exception ex){
          t.Rollback();
       }
     }
}

Однако, как я уже сказал, я задаюсь вопросом о необходимости явно распоряжаться транзакцией. Пожалуйста, порекомендуйте. Кстати, вышеупомянутый код достаточно безопасен (используя / закрывая сразу), чтобы использовать для опроса данных, таких как каждую секунду? Может ли он бомбардировать увеличением количества открытых соединений с целевой базой данных? Я не думаю, что держать соединение с длинным открытием хорошо в любом случае.

1 Ответ

0 голосов
/ 08 ноября 2019

Ознакомьтесь с документацией здесь Документы Microsoft

Вызов этого метода означает конец области транзакции. Если объект TransactionScope создал транзакцию и в области был вызван объект Complete, объект TransactionScope пытается зафиксировать транзакцию при вызове этого метода. В этом случае этот метод блокируется до завершения первой фазы обработки транзакции. Первый этап заканчивается после того, как все менеджеры ресурсов и зачисления в транзакцию проголосовали за результат транзакции, и TransactionManager прочно решил зафиксировать или прервать транзакцию. Второй этап обработки всегда асинхронный. Следовательно, нет никакой гарантии, что данные, только что зафиксированные в данной транзакции, будут немедленно доступны впоследствии, когда не будет использоваться другая транзакция для просмотра этих данных.

Использование конструкции с использованием C # гарантирует, что этот метод вызывается дажеесли происходит исключение. Исключения, возникающие после вызова этого метода, могут не повлиять на транзакцию. Этот метод также восстанавливает исходную транзакцию окружения. TransactionAbortedException генерируется, если транзакция на самом деле не зафиксирована.

По правде говоря, это было бы точно так же, если иметь предложение finally только с командой dispose. Но вы никогда не можете быть уверены, что следующий разработчик не будет делать что-то вроде этого:

using(var session = _sessionFactory.OpenSession()){
     using(var t = session.BeginTransaction()){
       try {
          //some code
          t.Commit();
       } catch(Exception ex){
          // Code the throws exception
          t.Rollback();
       } finally {
          // Some other code that throws exception
          // And then dispose
       }
     }
}

Таким образом, вместо синтаксического сахара, это также помогает убедиться, что все, что происходит, расположено правильно.

Вы можете проверить код здесь https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Impl/

В SessionImpl.cs вы обнаружите, что код ничего не делает для закрытия и / или удаления транзакции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...