2012-03-30 74 views
13

我想在Oracle 11g上使用NHibernate 3.2加速批量操作insert。要做到這一點我想使用NHibernate加速批量插入操作

Session.Save(entity); 
Session.Flush(); 
Session.Clear(); 

...我foreach循環,但有造成失蹤的Session對象異常:

未能懶洋洋地初始化角色的集合:MyClass.PropertyX,沒有會話或會話關閉

的另一種嘗試是設置批量大小:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory> 
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> 
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property> 
    <property name="connection.connection_string">xxx</property> 
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property> 
    <property name="adonet.batch_size">50</property> 
    <property name="query.substitutions">true=1, false=0</property> 
    <property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate</property> 
    </session-factory> 
</hibernate-configuration> 

另外我在代碼中設置Session.SetBatchSize(50)的有以下異常:

沒有批量大小爲會話工廠定義,配料是 禁用。設置adonet.batch_size = 1啓用批處理。

拋出此異常的唯一位置是NonBatchingBatcher,所以它看起來像我的會話有錯誤的批處理。

這裏有什麼問題?如何加快NHibernate的批量插入(不使用statlese會話)?

+0

你的第一個例外是什麼?另外,如果你在循環內執行'Flush' *,你不會分配任何東西。 – 2012-03-30 16:56:32

+0

@Diego Mijelshon添加了異常消息 – deamon 2012-04-02 07:55:20

+0

@deamon是以多線程的方式嗎? – Newbie 2012-04-04 19:05:12

回答

1

你爲什麼要清除會話?

我認爲你不應該清除循環中的會話。爲了確保將更改寫入數據庫,我寧願使用事務。

僞代碼:

foreach (var i in allElements) 
{ 
    using (var tx = session.BeginTransaction()) 
    { 
     ... do what you have to do with the object 
     tx.Commit(); 
    } 
} 

爲了加快速度還有其他的東西可以幫助 - 你必須定義什麼你真的想在循環做。

35

以下應該工作,

var testObjects = CreateTestObjects(500000); 

var stopwatch = new Stopwatch(); 
stopwatch.Start(); 
using (IStatelessSession session = sessionFactory.OpenStatelessSession()) 
using (ITransaction transaction = session.BeginTransaction()) 
{ 
    foreach (var testObject in testObjects) 
     session.Insert(testObject); 
    transaction.Commit(); 
} 

stopwatch.Stop(); 
var time = stopwatch.Elapsed; 

編號:具有值得一讀http://nhibernate.info/blog/2008/10/30/bulk-data-operations-with-nhibernate-s-stateless-sessions.html

+1

+1應該如何回答!爲我節省了時間 – user919426 2014-10-08 03:38:11

+0

使用無狀態會話後,我應該清除緩存嗎?或者有狀態會話是否會接受無狀態會話所做的更改? – 2015-01-29 07:54:32

4

以上所有提示都非常有效且非常有用。想要添加一個到集合:禁用日誌記錄。在控制檯中顯示你的SQL會顯着降低你的性能,正如使用NHProf進行性能分析,自動評論和格式化通過NLog或log4net記錄的SQL一樣。在我們的案例設置中:

cfg.AutoCommentSql = false; 
cfg.LogFormattedSql = false; 

將我們的大容量插入時間從大約6秒減少到剛過1秒。所以,雖然日誌記錄可能會幫助您確定更嚴重的問題,但它會帶來自身的性能提升!