问题描述
- web项目在执行大量的插入语句时执行一段时间后卡死
-
SSH框架,在页面有一个poi 批量导入excel的功能,每读取excel一行,保存为一个实体然后循环insert到DB里。刚开始程序运行正常,但是一段时间过后,系统出现卡死,不再执行insert sql ,刷新页面也没有响应,只能重启服务器。期间程序没有报错,myeclipse也不是内存溢出导致的卡死,因为点击其他功能模块时不会出现上述所说的问题,只有在执行大量的insert sql 时才会。
因为代码没有报错我也就不贴代码了。
我自己想的不知道是不是hibernate在做insert时由于数据量大导致链接关闭,但是我设置数据库连接池断开时间是1800s,事实上也没有超过。由于不知道hibernate底层的源码是怎样执行insert的,希望有大神说说,为什么在执行少量的insert时系统不会卡死,但处理大量数据并长时间insert的就是卡死。
虚心求各位指导!谢谢大家。如果有需要我会贴出代码。感谢。更改过后的代码,但是又有新的问题
@Override public void save(List<T> list) { long begin = System.currentTimeMillis(); Session session = getSession(); try { for (int i = 0; i < list.size(); i++) { session.save(list.get(i)); if (i%50 == 0 && i != 0) { session.flush(); session.clear(); } } } catch (Exception e) { e.printStackTrace(); } finally{ session.clear(); } long end = System.currentTimeMillis(); System.out.println((end-begin)/1000.0); }
这是basedao,是spring管理hibernate,加了2个属性
<prop key="hibernate.jdbc.fetch_size">100</prop> <prop key="hibernate.jdbc.batch_size">50</prop>
方法是根据不同的实体批量insert,虽然现在执行大量insert时不会中断,但是我有4个实体要连续执行批量insert,在insert完前2个实体后,我在第三个实体调用批量导入的方法设了断点,程序并没有停在断点上,又出现了卡死的情况。PS:不知道是不是在insert第二个实体那里就卡死了,还是说执行完第二个批量insert就卡死了,反正我在第三个批量insert方法前断点没进,并且系统卡死,只能重启。
请大家不吝赐教!感谢!
解决方案
就这种批量插入,就不要用hibernate了,直接jdbc调用sql的bulk copy插入。估计是你的事务造成死锁。
解决方案二:
http://www.360doc.com/content/14/0419/01/7669533_370197299.shtml
解决方案三:
你的大量插入代码是怎么样的呢?可以从POI读取一批数据后统一用sql的批量插入,避免不必要的数据库连接。
解决方案四:
http://blog.csdn.net/xiazdong/article/details/7709068
解决方案五:
这应该是没有定时清空缓冲区导致的吧
解决方案六:
不要每读一条都执行一次insert,这种性能很差,效率很差。
可以这样,你在代码里循环读取了1000条数据后,统一将这1000条数据批量插入到数据库中,然后再继续循环读取1000条再去调用批量插入方法,直到数据读取完。
不管怎么说批处理要比单条执行操作要好多了。至少这样的1000条数据就节省了999次的insert。
解决方案七:
处理大量数据并长时间insert看看你是一条条插入的,还是批量插入的,这个在数据多时性能影响是很大的