Как обернуть ленивую загрузку в транзакцию? - PullRequest
1 голос
/ 06 июня 2011

Я использую nhibernate и профиль nhibernate, который продолжает выдавать это предупреждение.

Использование скрытых транзакций не рекомендуется "

Я фактически обертываю все в транзакции через ninject

  public class NhibernateModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
            Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope()
                                                                                      .OnActivation(StartTransaction)
                                                                                      .OnDeactivation(CommitTransaction);
        }

        public void CommitTransaction(ISession session)
        {

            if (session.Transaction.IsActive)
            {
                session.Transaction.Commit();
            }

        }

        public void StartTransaction(ISession session)
        {
            if (!session.Transaction.IsActive)
            {
                session.BeginTransaction();
            }
        }
    }

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

Если загрузка ленивая, я получаю сообщение об ошибке. Что я делаю не так.

1 Ответ

1 голос
/ 15 августа 2011

Это, на самом деле, все еще неявная транзакция или относительно близкая к ней.Инжектор блаженно не знает обо всем, что произошло между активацией и деактивацией, и с радостью попытается зафиксировать все ваши изменения, даже если состояние неверно или повреждено.

Я вижу, что вы, по сути, пытаетесь обмануть ипросто сделайте так, чтобы Ninject автоматически запускал транзакцию в начале каждого запроса, и фиксировал транзакцию в конце каждого запроса, надеясь, что это остановит NH от жалоб.Это крайне плохой дизайн по нескольким причинам:

  1. Вы форсируете транзакцию, даже если сеанс вообще не используется (т. Е. Открытие поддельных соединений).
  2. Нет обработки исключений - если операция завершается неудачно или откатывается, код очистки просто игнорирует это и пытается все равно зафиксировать.
  3. Это приведет к хаосу, если вы когда-нибудь попытаетесь использовать TransactionScope, потому чтообласть действия будет завершена до того, как транзакция NH будет завершена.
  4. Вы теряете контроль над фактическим выполнением транзакций и теряете возможность (например) иметь несколько транзакций в одном запросе.

NH Profiler совершенно прав.Это неуместное использование транзакций NH.На самом деле, если вы лениво загружаете, транзакция может закончиться , пока вы все еще итерируете результаты - не очень хорошая ситуация.

Если вы хотите полезная абстракция над транзакционной логикой, и вам не нужно манипулировать объектами ISession, а затем использовать шаблон Unit Of Work - это то, для чего он предназначен.

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

...