nhibernate несколько приложений winforms - PullRequest
2 голосов
/ 16 февраля 2012

Я немного путаюсь с nhibernate и управлением кешем. У меня такая ситуация. Мы разрабатываем набор приложений win форм с использованием баз данных nhibernate и oracle. Что происходит? когда приложение изменяет данные на конкретном компьютере. измененные данные не отражаются на других компьютерах. Как будто nhibernate хранит данные в кеше. Но по конфигурации я думаю, что кеш отключен.

Пара вещей. Фабрика сеансов создается один раз в приложении. Это дорого создавать. И сеанс тоже открывается один раз и снова открывается, когда, например, возникает исключение. Я знаю, что открытие сессии один раз - не лучшая практика, но сейчас это то, что у нас есть.

Есть ли способ заставить nhibernate всегда получать данные из базы данных. Мы можем потерять представление, я знаю. Но важно получать данные, обновленные другими приложениями. Или у вас есть предложения по управлению ситуацией.

Это моя конфигурация гибернации

<?xml version="1.0" encoding="utf-8"?>
<!-- 
This template was written to work with NHibernate.Test.
Copy the template to your NHibernate.Test project folder and rename it in hibernate.cfg.xml and change it 
for your own use before compile tests in VisualStudio.
-->
<!-- This is the System.Data.OracleClient.dll provider for Oracle from MS -->
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <reflection-optimizer use="true"/>
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
    <property name="connection.connection_string">
      *******
    </property>
    <property name="show_sql">false</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
    <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
    <property name="cache.use_query_cache">false</property>
    <property name="cache.use_second_level_cache">false</property>
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
  </session-factory>
</hibernate-configuration>

Спасибо заранее. Я не знаю, что еще я могу показать, чтобы помочь мне решить эту проблему. Я считаю, что это проблема конфигурации.

Pd: мы используем общий репозиторий от Бесника. http://code.google.com/p/genericrepository/

--- отредактировано ----

Так я использую транзакции

public Pedido Crear(Barra barra, Casillero casillero, Empleado empleado, String codigoEmpleado)
        {
            DateTime fecha = DBService.GetCurrentDateTime();
            Pedido pedido = new Pedido
                                {
                                    Barra = barra,
                                    Casillero = casillero,
                                    Empleado = empleado,
                                    EmpleadoCodigo = codigoEmpleado,
                                    FechaCreacion = fecha
                                };
            Transaction.Transaction.Execute(() => pedidoRepository.Insert(pedido));
            return pedido;
        }

PedidoRepository

namespace Services.Repository.Hibernate
{
    /// <summary>
    /// Implementación del repositorio
    /// </summary>
    class PedidoRepositoryImplementation : GenericRepository<Pedido, long>, PedidoRepository
    {

        /// <summary>
        /// Constructor
        /// </summary>
        public PedidoRepositoryImplementation(IUnitOfWork unitOfWork, ISpecificationLocator specificationLocator)
            : base(unitOfWork, specificationLocator)
        {
        }
    }
}

класс транзакции

    public sealed class Transaction
    {

        public static void Execute(Action transactionalAction, Action<Exception> onException = null)
        {
            if (onException == null)
                onException = WhenException;
            if (transactionalAction != null)
                using (ITransaction transaction = DI.Get<IUnitOfWork>().BeginTransaction())
                {
                    try
                    {
                        transactionalAction();
                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {

                        if (transaction != null)
                            transaction.Rollback();
                        DI.Get<Logger>().exception(ex);
                        IUnitOfWork uwork = DI.Get<IUnitOfWork>();
                        var session = (NHibernate.ISession)ReflectionUtils.GetPropertyValue(uwork, "Session");
                        var last = session;
                        session = session.SessionFactory.OpenSession();
                        ReflectionUtils.SetPropertyValue(uwork, "Session", session);
                        last.Close();
                        last.Dispose();
                        onException.Invoke(ex);
                    }
                }
        }

        private static void WhenException(Exception ex)
        {

            ******
        }
    }

вот как я регистрирую IUnitOfWork

//Register the Hibernate Factory
            builder.Register(i => new NHibernateUnitOfWorkFactory(hibernateFilePath));
            builder.Register(i => DI.Get<NHibernateUnitOfWorkFactory>().BeginUnitOfWork()).As<IUnitOfWork>().SingleInstance();

Вот как бесник использует единицу работы, когда я вставляю данные (взятые из исходного кода)

 public virtual void Insert(TEntity entity)
                {
                        this.UnitOfWork.Insert<TEntity>(entity);
                }

Ответы [ 2 ]

4 голосов
/ 16 февраля 2012

Данные сохраняются в базе данных при совершении транзакции (конечно, вы должны что-то изменить).Вы не используете какой-либо кэш второго уровня, поэтому единственный кэш, который вы можете использовать, - это кэш первого уровня во время сеанса.Таким образом, вам, вероятно, нужно улучшить управление сеансами в вашем приложении, чтобы увидеть, как все меняется (ваш сеанс слишком много?), В противном случае объекты, выбранные после того, как они останутся в сеансе, устарели.Взгляните на это обсуждение , чтобы улучшить свою стратегию.

0 голосов
/ 16 февраля 2012

По умолчанию NH сбрасывает сессию (отправляет измененные данные в базу данных) при вызове метода ITransaction.Commit ().Это поведение контролируется перечислением FlushMode.Из вашего вопроса не ясно, когда вы открываете и фиксируете транзакцию, но вы можете попытаться вызвать session.Flush (), чтобы заставить NH немедленно сохранить ваши изменения.

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