2012-02-16 78 views
2

我有點困惑與nhibernate和緩存管理。 我有這種情況。我們正在使用nhibernate和oracle數據庫開發一組勝利形式的應用程序。 會發生什麼?當應用程序修改特定PC中的數據時。修改後的數據不會反映在其他電腦上。這就像nhibernate將數據保存在緩存中一樣。但通過配置我認爲緩存被禁用。nhibernate多個winforms應用程序

一些事情。會話工廠在應用程序中創建一次。創造成本很高。會話也會打開一次,例如發生異常時會重新打開。我知道,開一次會議並不是一個好習慣,但現在就是我們所擁有的。

有沒有辦法強制nhibernate總是從數據庫中檢索數據。我知道,我們可能會失去表演。但重要的是檢索其他應用程序更新的數據。 或者你有什麼建議來管理這種情況。

這是我的Hibernate配置提前

<?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> 

感謝。 我不知道我還能展示什麼來幫助我解決這個問題。我beleave是一個配置問題。

Pd:我們正在使用Besnik的通用存儲庫。 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); 
       } 

回答

4

數據被持久保存在數據庫中,當您提交一個換位(當然你應該修改一些東西)。您沒有使用任何二級緩存,因此您可能觸及的唯一緩存是第一級緩存,在會話範圍內。因此,您可能需要在應用程序上實施會話管理,以查看事情正在發生變化(您的會話是否過多?),否則實體會一直保持會話狀態。 查看this discussion以改善您的策略。

+0

感謝您的回答。是的,會議期間很多。如果沒有發生異常,則直到應用程序關閉。 – 2012-02-16 13:07:33

+0

也許你會發現這個答案很有用:http:// stackoverflow。com/questions/874981/nhibernate-win-forms-session-management – 2012-02-16 13:08:44

+2

保持會話的持續時間短 - 就好像它是Web應用程序中每個請求的會話一樣。如果你使用using語句包裝會話,則不需要顯式調用session.flush。一級緩存只能持續一段時間。 – 2012-02-16 13:41:35

0

默認情況下,當調用ITransaction.Commit()方法時,NH刷新會話(將修改後的數據發送到數據庫)。此行爲由FlushMode枚舉控制。當你打開並提交事務時,你的問題並不清楚,但你可以嘗試調用session.Flush()來強制NH立即保存你的改變。

+0

數據提交得很好。使用oracle工具查看數據庫中反映的更改。我認爲這不是問題。我會編輯我的答案,並告訴你我如何使用交易 – 2012-02-16 13:26:48