17

文档

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

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();

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

    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();

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

4

3 回答 3

10

从您链接到的文档中:

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

这些是一些重要的限制!

如果您正在创建的对象或您所做的修改是对单个对象的标量字段的简单更改,那么我认为与批处理正常会话相比,无状态会话没有缺点。然而,一旦你想做一些更复杂的事情——比如操作一个对象的集合值属性,或者另一个从第一个级联的对象——那么无状态会话更多的是障碍而不是帮助。

更一般地说,如果批处理的普通会话提供了足够好的性能,那么无状态会话只是不必要的复杂性。它看起来有点像普通的会话,但它有不同的 API 和不同的语义,这是一种会招致 bug 的东西。

当然,在某些情况下它是合适的工具,但我认为这些是例外而不是规则。

于 2013-01-05T17:28:03.830 回答
1

无状态会话在性能方面优于 Session,因为无状态会话将跳过事务提交到会话对象中使用的会话或会话刷新方法。但是,重要的是要注意服务/DAO 不应尝试对父对象或任何子对象执行会话中数据操作。它会抛出异常。此外,请确保明确关闭会话,否则最终会导致连接泄漏。

为了通过无状态会话获得更多性能,如果使用 Spring 驱动的事务,请将 Spring 事务标记为只读并将所需的传播设置为 NEVER。

但同样,不要在必须操纵对象模型的情况下尝试这种做法。

@Transactional(value="someTxnManager", readOnly=true, propagation=Propagation.NEVER)
    public List<T> get(...) {

        return daoSupport.get(...);
    }

在 daoSupport

StatelessSession session = sessionFactory.openStatelessSession();
try{
// do all operations here
}
...
...
finally{
            session.close();
}
于 2015-02-12T21:12:37.077 回答
-9

StatelessSession 不支持批处理。
如果我没记错的话,我已经在文档中看到了这一点
StatelessSession 未提供的功能和行为
• 一级缓存
• 与任何二级缓存或查询缓存的交互
• 事务性后写或自动脏检查

以及使用缓存进行批处理
原谅我如果我错了。

于 2013-01-19T15:01:30.280 回答