使用StatelessSession进行批处理 [英] Using StatelessSession for Batch processing

查看:89
本文介绍了使用StatelessSession进行批处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

文件

p>

如果我们有一个需要插入1000 000个行/对象的情况:

  Session session = sessionFactory.openSession(); 
Transaction tx = session.beginTransaction();

(int i = 0; i <100000; i ++){
Customer customer = new Customer(.....);
session.save(customer);
if(i%20 == 0){// 20,与JDBC批量大小相同
//刷新一批插入并释放内存:
session.flush();
session.clear();
}
}

tx.commit();
session.close();

为什么我们应该使用这种方法?它给我们带来了什么样的好处,与StatelessSession相比:

pre $ StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();

(int i = 0; i <100000; i ++){
Customer customer = new Customer(.....);
session.insert(customer);
}

tx.commit();
session.close();

我的意思是,这个(替代)最后一个例子不使用内存,不需要同步,清理缓存,那么这应该是这种情况下的最佳做法?为什么要用上一个呢?

解决方案

从您链接到的文档:


特别是,无状态会话不会实现一级缓存,也不会与任何二级或查询缓存进行交互。它没有实现事务性的后写或自动脏检查。使用无状态会话执行的操作不会级联到关联的实例。集合被无状态会话忽略。通过无状态会话执行的操作绕过了Hibernate的事件模型和拦截器。由于缺乏一级缓存,无状态会话容易受到数据混叠效应的影响。


这些都是一些重要的限制! / p>

如果您正在创建的对象或您所做的修改是对单个对象的标量字段的简单更改,那么我认为无状态会话将不会与批量正常会话相比的缺点。然而,只要你想做一些更复杂的事情 - 操纵一个对象的集合值属性或另一个从第一个级联的对象,比如说 - 那么无状态会话就是一个阻碍,而不是帮助。 / p>

更一般地说,如果批处理的普通会话提供足够好的性能,那么无状态会话就是不必要的复杂性。它看起来很像普通会话,但它有不同的API和不同的语义,这就是引发错误的事情。



肯定会出现这种情况是适当的工具,但我认为这些是例外而非规则。


From documentation

If we have a case where we need to insert 1000 000 rows/objects:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}

tx.commit();
session.close();

Why we should use that approach? What kind of benefit it brings us comparing to StatelessSession one:

    StatelessSession session = sessionFactory.openStatelessSession();
    Transaction tx = session.beginTransaction();

    for ( int i=0; i<100000; i++ ) {
      Customer customer = new Customer(.....);
      session.insert(customer);
    }    

    tx.commit();
    session.close();

I mean, this ("alternative") last example does not use memory, no need to synchronize, clean out of the cache, then this supposed to be best practice for cases like this? Why to use previous one then?

解决方案

From the documentation you link to:

In particular, a stateless session does not implement a first-level cache nor interact with any second-level or query cache. It does not implement transactional write-behind or automatic dirty checking. Operations performed using a stateless session never cascade to associated instances. Collections are ignored by a stateless session. Operations performed via a stateless session bypass Hibernate's event model and interceptors. Due to the lack of a first-level cache, Stateless sessions are vulnerable to data aliasing effects.

Those are some significant limitations!

If the objects you're creating, or the modifications you're making, are simple changes to scalar fields of individual objects, then i think that a stateless session would have no disadvantages compared to a batched normal session. However, as soon as you want to do something a bit more complex - manipulate a collection-valued property of an object, or another object which is cascaded from the first, say - then the stateless session is more a hindrance than a help.

More generally, if the batched ordinary session gives performance that is good enough, then the stateless session is simply unnecessary complexity. It looks vaguely like the ordinary session, but it has a different API and different semantics, which is the sort of thing that invites bugs.

There can certainly be cases where it is the appropriate tool, but i think these are the exception rather than the rule.

这篇关于使用StatelessSession进行批处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆