【问题标题】:nhibernate : executing updates in batchesnhibernate : 批量执行更新
【发布时间】:2016-12-22 12:45:52
【问题描述】:

我正在尝试使用 NHibernate 进行批量更新,但它没有进行批量更新,而是对所有行进行单独写入。我必须向 db 写入大约 10k 行。

        using (var session = GetSessionFactory().OpenStatelessSession())
        {
            session.SetBatchSize(100);
            using (var tx = session.BeginTransaction())
            {
                foreach (var pincode in list)
                {
                    session.Update(pincode);
                }
                tx.Commit();
            }
        }

我尝试使用session.SetBatchSize(100); 将批量大小设置为 100,但这无济于事。还尝试使用cfg.SetProperty("adonet.batch_size", "100"); 设置批量大小,但这也无济于事。

我正在使用 GUID 主键,因此我不明白批量更新失败的原因。这正是here 解释的解决方案。但它不适合我。

注意我在所有实体上都映射了乐观并发的版本字段。这会是没有批量更新的罪魁祸首吗??

编辑

我尝试使用有状态会话,但这也没有帮助

        //example 2
        using (var session = GetSessionFactory().OpenSession())
        {
            session.SetBatchSize(100);
            session.FlushMode = FlushMode.Commit;
            foreach (var pincode in list)
            {
                session.Update(pincode);
            }
            session.Flush();
        }

       //example 3
        using (var session = GetSessionFactory().OpenSession())
        {
            session.SetBatchSize(100);
            using (var tx = session.BeginTransaction())
            {
                foreach (var pincode in list)
                {
                    session.Update(pincode);
                }
                tx.Commit();
            }
        }

example 2 出于某种原因导致了两次往返。

编辑

经过进一步研究我发现,每个 session.Update 实际上都是在更新数据库

        using (var session = SessionManager.GetStatelessSession())
        {
            session.SetBatchSize(100);
            foreach (var record in list)
            {
                session.Update(record);
            }
        }

我怎样才能避免这种情况。

编辑

也尝试过刷新模式,但这也无济于事

        using (var session = SessionManager.GetNewSession())
        {
            session.FlushMode = FlushMode.Never;
            session.SetBatchSize(100);
            session.BeginTransaction();
            foreach (var pincode in list)
            {
                session.SaveOrUpdate(pincode);
            }
            session.Flush();
            session.Transaction.Commit();
        }

编辑 4

即使低于一个也不起作用,因为我正在获取同一会话中的所有实体并仅在该会话中更新和保存它们...

        using (var session = SessionManager.GetSessionFactory().OpenSession())
        {
            session.SetBatchSize(100);
            session.FlushMode = FlushMode.Commit;
            session.Transaction.Begin();
            var list = session.QueryOver<Pincode>().Take(1000).List();
            list.ForEach(x => x.Area = "Abcd" + DateTime.Now.ToString("HHmmssfff"));
            foreach (var pincode in list) session.SaveOrUpdate(pincode);
            session.Flush();
            session.Transaction.Commit();
        }

【问题讨论】:

  • 如果您的“pincode”是代理,您不需要调用session.Update(pincode); 如果是这样,如果您更改实体并调用session.Flush();,会发生什么?
  • 不,这些不是代理,这些对象是在另一个无状态会话中从数据库中获取的,应用了一些业务逻辑,然后批量保存...
  • 在这种情况下,请参阅下面奥斯卡的回答。
  • 但即使有状态会话也是如此,请参阅示例 2、示例 3 和最近的编辑...批量更新没有任何效果
  • 据我所知,如果您的实体是从不同的会话中获取的,那么您仍然是无状态的。尝试使用相同的有状态会话获取、更改实体和提交。看看这是否有效。

标签: nhibernate


【解决方案1】:

您正在使用无状态会话。由于无状态会话没有状态,因此它无法记住以后要做的任何事情。因此更新会立即执行。

【讨论】:

  • 就我而言,NHibernate 无状态会话根本没有刷新更新。解决方法是 SetBatchSize(1)。
【解决方案2】:

nhibernate 不批处理版本化实体这是我的问题。

没有办法批量版本实体,唯一的做法是使实体不版本化。

【讨论】:

    【解决方案3】:

    注意:

    • 批次在 Sql Server Profiler 中不可见。不要依赖于此。
    • 当使用 identity(或本机)ID 生成器插入时,NH 会关闭 ado.net 批量大小。

    补充说明:

    • 确保您没有针对每个已更改实体的查询,因为它会在查询之前刷新。
    • 您可能不应该调用 session.Update。在最好的情况下,它什么也不做。在最坏的情况下,它确实会更新,从而破坏批处理。

    当会话中有许多对象时,不要忘记关心刷新和刷新时间。有时刷新比更新更耗时。 NH 在提交之前刷新,当您调用刷新和查询之前,除非您将其关闭或使用无状态会话。确保只冲洗一次。

    【讨论】:

    • 1.我正在使用 NHProf,2。我有 GUID 主键。还要检查 EDIT4,至少应该与 session-flush 一起使用
    • 除了这两个之外,还有什么其他条件会破坏批处理??
    • 批处理是由ado.net实现的,所以必须使用ado.net访问数据库。
    • 插入是批处理的,所以并不是批处理不起作用......它适用于插入但不适用于更新。
    • 我还检查了 nhibernate 日志,但日志中没有任何内容可以说明,为什么它不使用批处理,每次在 abstract-batcher 中处理单个更新。
    猜你喜欢
    • 2010-10-21
    • 1970-01-01
    • 2012-03-13
    • 2011-04-05
    • 2014-02-20
    • 2015-08-03
    • 2020-10-18
    相关资源
    最近更新 更多