Hibernate 批处理(batch inserts, updates and deletes)

总结:hibernate在进行批量处理不给力的主要原因就是Session中存在缓存,而hibernate的机制就是通过session中的一级缓存去同步数据库,所以当进行批量处理时,缓存中保存的数据量很大时会消耗很大内存资源,造成各种崩溃。

  其实平时工作中用到大量的批处理数据还是挺少的,很少遇到有上万条数据的批处理的,但是要是遇到了用hibernate去处理还是很纠结的,然后就去Hibernate官网看了看有没有啥处理方法学习下。

  刚工作的时候用hibernate还不是很熟练,遇到批处理的时候就直接切到JDBC做处理,比较混搭的风格。但是感觉看上去代码风格就不是很好的感觉。

  批量插入:

  如果有10w条数据需要插入到数据库中用hibernate做起来可能会比较困难。

  比较too young too naive的做法就是循环:

1 Session session = sessionFactory.openSession();
2 Transaction tx = session.beginTransaction();
3 for ( int i=0; i<100000; i++ ) {
4     Customer customer = new Customer(.....);
5     session.save(customer);
6 }
7 tx.commit();
8 session.close();

  这样做法大概会在5w条数据时候跳出OutOfMemoryExcepiton,因为hibernate的一级缓存原因,会把数据都先缓存到session中,等事务commit或者flush的时候才会把数据同步到数据库中,数据量太大时候session就hold不住了你懂的。

  可以有个小聪明的做法,用下面方法之前,记得开启JDBC的批处理,在hibernate配置文件中设置hibernate.jdbc.batch_size属性值在10到50之间

 1 Session session = sessionFactory.openSession();
 2 Transaction tx = session.beginTransaction();
 3
 4 for ( int i=0; i<100000; i++ ) {
 5     Customer customer = new Customer(.....);
 6     session.save(customer);
 7     if ( i % 20 == 0 ) { //20, 和配置文件中hibernate.jdbc.batch_size属性值一致
 8
 9         session.flush();  //强制刷新session中的缓存到数据库中
10         session.clear();  //清除session中的缓存,ps:evict()干掉session中一个实例的缓存
11     }
12 }
13
14 tx.commit();
15 session.close();

  批量更新:

  批量更新的时候也可以利用fulsh()和clear()方法来定期的清楚session中的缓存,方法和上面的批量插入一样。除此之外,还可以用scroll()方法来处理当你想从数据库查询大量数据并想更新这些数据的时候,貌似有点游标的感觉啊:

  

 1 Session session = sessionFactory.openSession();
 2 Transaction tx = session.beginTransaction();
 3
 4 ScrollableResults customers = session.getNamedQuery("GetCustomers")
 5     .setCacheMode(CacheMode.IGNORE)  // 设置cache模式为:这个session不会和cache有任何联系,不使用cache
 6     .scroll(ScrollMode.FORWARD_ONLY);
 7 int count=0;
 8 while ( customers.next() ) {
 9     Customer customer = (Customer) customers.get(0);
10     customer.updateStuff(...);
11     if ( ++count % 20 == 0 ) {
12         //同步数据并且释放内存:
13         session.flush();
14         session.clear();
15     }
16 }
17
18 tx.commit();
19 session.close();
org.hibernate.CacheMode的常量字段有:  GET    session会从缓存中读取数据,但是不会把数据增加到缓存中,除非把缓存中的数据更新为无效数据时  IGNORE  session不和任何缓存有交互操作,除非把缓存中的数据更新为无效数据时  PUT    session不会从缓存中读取数据,但是会把从数据库中读取的数据增加到缓存中  REFRESH  session不从缓存中读取数据,但是会把从数据库读取的数据增加到缓存中,和PUT不同的是会忽略配置文件中的hibernate.cache.use_minimal_puts属性,就是为了强制刷新缓存

 org.hibernate.ScrollMode的常量字段有:

  FORWARD_ONLY: 请求一个类似游标的结果集,并且只转发这个结果集

  SCROLL_INSENSITIVE:请求一个游标的结果集,并且对基础数据的变化不敏感

  SCROLL_SENSITIVE:请求一个游标的结果集,并且对基础数据变化敏感

  没有怎么用过这个属性,不怎么清楚是什么意思。以后有空会再研究下补充上来

通过StatelessSession来进行批处理

 1 StatelessSession session = sessionFactory.openStatelessSession();
 2 Transaction tx = session.beginTransaction();
 3
 4 ScrollableResults customers = session.getNamedQuery("GetCustomers")
 5     .scroll(ScrollMode.FORWARD_ONLY);
 6 while ( customers.next() ) {
 7     Customer customer = (Customer) customers.get(0);
 8     customer.updateStuff(...); //做一些更新操作
 9     session.update(customer);
10 }
11
12 tx.commit();
13 session.close();
Notes:通过StatelessSession查询返回的Customer的实例立刻会成为游离状态,不会关联到任何的持久化层的上下文中也不会和缓存有任何关联。因为StatelessSession本身也不包括一级缓存,所以就不用考虑有缓存溢出的问题。

  Notes:StatelessSession没有一级缓存,也不会和二级缓存和其他缓存有任何交互,不会隐式产生transaction更没有脏数据检查。

  StatelessSession是一个比较低级别的十分接近底层JDBC的抽象接口。它定义的insert(),update()和delete()的方法都是直接作用到数据库的数据中。和直接使用JDBC的SQL操作数据库效果一样,但是和Session接口中的save(),saveOrUpdate()还有delete()定义的操作有很大的不同。

最后的方法是可以通过HQL进行数据库的批量操作。这个会在后面的文章中继续提到的。

  下面是官方的原文,请原谅我的盗版:

http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch04.html

时间: 2024-08-19 08:45:33

Hibernate 批处理(batch inserts, updates and deletes)的相关文章

批处理(Batch)---批处理脚本。

批处理(Batch),也称为批处理脚本.顾名思义,批处理就是对某对象进行批量的处理,通常被认为是一种简化的脚本语言,它应用于DOS和Windows系统中.批处理文件的扩展名为bat .目前比较常见的批处理包含两类:DOS批处理和PS批处理.PS批处理是基于强大的图片编辑软件Photoshop的,用来批量处理图片的脚本:而DOS批处理则是基于DOS命令的,用来自动地批量地执行DOS命令以实现特定操作的脚本.更复杂的情况,需要使用if.for.goto等命令控制程式的运行过程,如同C.Basic等高

关于Hibernate级联更新插入信息时提示主键不为空的问题“org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1 ”

org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1 出现这一错误的主要原因有两个       使用的是hibernate的saveOrUpdate方法保存实例.saveOrUpdate方法要求ID为null时才执行SAVE,在其它情况下执行UPDATE.在保存实例的时候是新增,但你的ID不为null,

Hibernate批处理操作优化 (批量插入、更新与删除)

问题描述 我开发的网站加了个新功能:需要在线上处理表数据的批量合并和更新,昨天下午发布上线,执行该功能后,服务器的load突然增高,变化曲线异常,SA教育了我一番,让我尽快处理,将CPU负载降低. 工作所需,我经常要写些程序批量处理数据,每次执行几十万数据处理的时候,我机子的CPU都会飙高,而且数据处理速度会越来越慢.比如第一个1W条要5分钟,第二个1W条就要10分钟,要干其他事情的时候机子也卡的不行,只能等着处理完数据. 其实我一直认为是数据量太大,从来不认为是程序问题,所以一直没怎么关注过.

Performance Tuning of Spring/Hibernate Applications---reference

http://java.dzone.com/articles/performance-tuning For most typical Spring/Hibernate enterprise applications, the application performance depends almost entirely on the performance of it's persistence layer. This post will go over how to confirm that

Spring 事务源码分析——Hibernate篇

在Spring与Hibernate整合的时候,可以利用Spring的事务管理机制,为我们管理事务的开启.提交.回滚等操作.这样的方式极大的减少了我们的代码量,让我们只专注于业务代码的编写.在使用Hibernate的时候,每一个操作都要经历事务开启与提交这样的操作,他们在业务代码的周围,这样来看是不是就想到了AOP编程,把这部分代码抽取出来.没错,Spring正是这样做的,Spring的事务管理就是基于AOP的. 1 Spring的事务隔离与传播 Srping的事务定义了五个隔离等级(isolat

spring 声明式事务原理解读

在Spring中,声明式事务是通过事务属性(transaction attribute)来定义的.事务属性描述了事务策略如何应用到方法上.事务属性包含5个方面: 传播行为 隔离级别 是否只读 事务超时 回滚规则 尽管Spring提供了多种声明式事务的机制,但是所有的方式都依赖这五个参数来控制如何管理事务策略. (上述内容参考<Spring In Action>第三版). 对于声明式事务是使用Spring提供的tx配置命名空间.其中一些声明式事务配置元素依赖于部分Spring的AOP配置元素.

OData

http://scn.sap.com/docs/DOC-44986 Introduction OData services provide a uniform interface for interacting with their resources, and in addition are self-describing: The service document (located at the service root) lists the available top-level reso

MySQL 5.6 Reference Manual-14.6 InnoDB Table Management

14.6 InnoDB Table Management 14.6.1 Creating InnoDB Tables 14.6.2 Moving or Copying InnoDB Tables to Another Machine 14.6.3 Grouping DML Operations with Transactions 14.6.4 Converting Tables from MyISAM to InnoDB 14.6.5 AUTO_INCREMENT Handling in Inn

SQL Server Lock Escalation - 锁升级

Articles Locking in Microsoft SQL Server (Part 12 – Lock Escalation) http://dba.stackexchange.com/questions/12864/what-is-lock-escalation 2008 R2 Lock Escalation (Database Engine) ---Forward from Locking in Microsoft SQL Server (Part 12 – Lock Escala