系统有一个自动计时触发的程序,此程序需要执行上万条修改语句的SQL,执行时间有一二十分钟。执行过程中总是导致系统崩溃。请问这是为什么?一般来说我直接执行几万条SQL语句最多也就10来秒就完了。有什么解决方案?以下是UPDATE语句,用了hibernate的。条件B,C为主键。UPDATE TEST t SET t.A=? WHERE t.id.B=? AND t.id.C=?以下是核心的执行代码,全部添加进一个LIST然后调用此方法执行:Transaction tx = session.beginTransaction();
try {
for (int i = 0; i < hqlList.size(); i++) {
Query query = session.createQuery(hqlList.get(i));

if (i < parList.size()) {
List pars = (List) parList.get(i);
for (int j = 0; j < pars.size(); j++) {
query.setParameter(j, pars.get(j));
}
}
query.executeUpdate(); if (i % 20 == 0) { 

session.flush();
session.clear();
}
}
tx.commit();

解决方案 »

  1.   

    首先不知道LZ的定时是怎么处理?是多线程还是单线程?
    如果是单线程的话,如果处理太慢,上一次定时没做完,下一次定时肯定被堵塞着(此时的下一次处理的数据信息是如何保存的?),这样的每次累计的定时堵塞就会越来越多
    如果是多线程的话,list之间的同步保证了没有,数据库的死锁保证了没有,因为多线程的话,可能是多个事务并行,那么更新的数据如果有影响,比如线程1要更新数据1,但是线程2已经更新了,但是还没commit,那么线程1就会等待,同样的,线程2也有可能发生等待,于是就有可能发生死锁
      

  2.   


    是单线程,而且这个任务就只执行3个SQL语句,一个增加,两个修改,并且三个SQL语句操作的都不是同一个表,另外两个由于数据量比较小所以很快就执行完了,就是这个修改的要执行很久,所以应该不存在堵塞的情况。
      

  3.   

    用SQLQuery  执行update语句
    你的UPDATE TEST t SET t.A=? WHERE t.id.B=? AND t.id.C=? 应该的查询得到的结果吧!
    可以用select for update 
      

  4.   


    谢谢这位兄弟,不过我这个不需要查询,因为原始数据是这个任务前一个小时同步过来的,所以A字段一直为空的。这个SQL的作用就是用另外一个接口的数据把这个表的A字段补充完整。
      

  5.   

    那就用jdbc的批处理器,这个对批量更新,批量新增效率比直接用hibernate这样更新效率高!
           Connection conn = getSession().connection();
          PreparedStatement pst = null;
          try {
    conn.setAutoCommit(false);
            String sql = "UPDATE TEST t SET t.A=? WHERE t.id.B=? AND t.id.C=?";
            pst = conn.prepareStatement(sql);
            for(int i = 0; i < hqlList.size(); i++){
               //根据数据类型设置参数如
                 //每个?都要设置参数,参数从1开始
                 pst.setInt(第几个参数,参数的值);
               pst.addBatch();
            }
            pst.executeBatch();
            conn.commit();
           catch(Exception e){
           }
      

  6.   

    第一先从硬件入手 换好的服务器第二 软件  :增加虚拟机内存 -Xmx512第三:代码改善