【问题标题】:Nhibernate large transactions, flushes vs locks休眠大事务,刷新与锁定
【发布时间】:2013-11-18 03:52:33
【问题描述】:

我在使用 Nhibernate 维护一个非常大的事务时遇到了挑战。所以,让我们说,我正在保存大量实体。如果我不刷新事务 N,让我们说 10000,那么性能会由于 Nh 会话过度拥挤而被扼杀。如果我进行刷新,我会在 DB 级别上放置锁,这与已提交的读取隔离级别相结合确实会影响工作应用程序。另请注意,实际上我导入了一个实体,其业务逻辑是系统的核心之一,并且在其导入时大约有 10 个表受到影响。由于手动维护级联,这使得无状态会话成为一个坏主意。

将 BL 迁​​移到存储过程是一个很大的挑战,原因如下:

  1. 领域中已经存在复杂的OO业务逻辑 应用类别,
  2. 将引入重复的 BL。

理想情况下,我想将会话刷新到某个文件,然后才完成数据准备,我想执行其内容。有可能吗?

非常欢迎任何其他建议/最佳做法。

【问题讨论】:

    标签: c# sql-server nhibernate


    【解决方案1】:

    您的场景是典型的 ORM 批处理问题。一般来说,我们可以说没有 ORM 是用来做这样的事情的。如果您想获得较高的批处理性能(不是永久锁,也可能是死锁),您不应该使用 ORM 插入 1000 条记录。

    改为使用本机批量插入,这总是会快很多。 (例如 SqlBulkCopy 用于 MMSQL)

    无论如何,如果您想为此使用 nhibernate,请尝试使用批量大小设置。 对所有对象调用保存或更新,最后只调用一次session.Flush。这将在内存中创建所有对象...

    根据批处理大小,nhibernate 应该尝试创建具有此大小的插入/更新批处理,这意味着您将减少到数据库的往返次数,因此锁更少,或者至少不应该花费那么长时间...

    一般来说,如果您使用普通事务,您的操作应该只在您的第一个插入语句在服务器上执行时锁定数据库。如果您使用TransactionScope,它的工作方式可能会有所不同。

    这里有一些关于如何改进批处理的附加信息。

    http://fabiomaulo.blogspot.de/2011/03/nhibernate-32-batching-improvement.html NHibernate performance insert http://zvolkov.com/clog/2010/07/16?s=Insert+or+Update+records+in+bulk+with+NHibernate+batching

    【讨论】:

    • 问题是我买不起不刷新,瓶颈是往返。问题是我必须刷新,否则性能会被杀死,但是一旦我刷新我在数据库中有数千个锁
    • 如果在创建每个对象后刷新,就性能而言,往返不是瓶颈,但是在插入内容的那一刻你会得到锁。并且当事务打开时,锁不会被释放。这意味着您在执行第一次“真正”插入之前汇集的对象越多,对您的应用程序就越好...您拥有的往返次数越多,整个过程所需的时间就越长...正如我所说,您有 2 个选项,无论是批处理您的数据,或者如果您使用 SQL Server,则使用 SQL Server 的本机批处理
    • 我会刷新每 N 个实体(我们说 5000 个),否则会话附加的对象太多,速度太慢。第一次刷新导致 SQL 正在执行。另请注意,我已经实施并实施了批处理,但它没有帮助
    • 好的,如果你已经这样做但仍然无法正常工作,你最好的选择是使用SqlBulkCopy,正如我所说的msdn.microsoft.com/en-us/library/…,它也适用于nhibernate事务......stackoverflow.com/questions/2006024/…跨度>
    猜你喜欢
    • 2012-04-14
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    相关资源
    最近更新 更多