我面临着使用Nhibernate维护一个难以置信的大事务的挑战。所以,让我们说,我正在拯救大量的实体。如果我不使用事务N (假设为10000 ),那么性能就会因为Nh会话过度拥挤而被扼杀。如果我进行刷新,我会将锁放在DB级别上,这与读取提交的隔离级别结合在一起确实会影响工作应用程序。还请注意,实际上,我导入了一个实体,其业务逻辑是系统的核心之一,在其导入时,大约有10个表受到影响。这使得无状态会话成为一个糟糕的主意,因为手工维护级联。
将BL移动到存储过程是一个很大的挑战,原因是:
理想情况下,我希望将会话刷新到某个文件,只有在数据准备完成之后,我才希望执行它的内容。有可能吗?
任何其他建议/最佳做法都非常受欢迎。
发布于 2013-11-17 11:30:54
您的场景是典型的ORM批处理问题。一般来说,我们可以说,ORM并不是用来做那样的事情的。如果您希望具有较高的批处理性能(而不是永久锁或死锁),则不应使用ORM插入1000 s的记录。
相反,使用本机批处理插入,这将总是要快得多。(类似于MMSQL的SqlBulkCopy )
无论如何,如果要为此使用nhibernate,请尝试使用批处理大小设置。调用、保存或更新所有对象,最后只调用session.Flush
一次。这将在内存中创建所有的对象..。
根据批处理大小,nhibernate应该尝试创建具有此大小的insert/update批处理,这意味着您对数据库的往返次数将大大减少,因此锁会更少,或者至少不会花那么长时间.
通常,如果使用正常事务,操作只应在服务器上执行第一个insert语句时锁定数据库。如果使用TransactionScope
,它的工作方式可能会有所不同。
下面是一些关于如何改进批处理的附加读物。
http://fabiomaulo.blogspot.de/2011/03/nhibernate-32-batching-improvement.html NHibernate性能插入 http://zvolkov.com/clog/2010/07/16?s=Insert+or+Update+records+in+bulk+with+NHibernate+batching
https://stackoverflow.com/questions/20034979
复制相似问题