系统有一个自动计时触发的程序,此程序需要执行上万条修改语句的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();
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();
如果是单线程的话,如果处理太慢,上一次定时没做完,下一次定时肯定被堵塞着(此时的下一次处理的数据信息是如何保存的?),这样的每次累计的定时堵塞就会越来越多
如果是多线程的话,list之间的同步保证了没有,数据库的死锁保证了没有,因为多线程的话,可能是多个事务并行,那么更新的数据如果有影响,比如线程1要更新数据1,但是线程2已经更新了,但是还没commit,那么线程1就会等待,同样的,线程2也有可能发生等待,于是就有可能发生死锁
是单线程,而且这个任务就只执行3个SQL语句,一个增加,两个修改,并且三个SQL语句操作的都不是同一个表,另外两个由于数据量比较小所以很快就执行完了,就是这个修改的要执行很久,所以应该不存在堵塞的情况。
你的UPDATE TEST t SET t.A=? WHERE t.id.B=? AND t.id.C=? 应该的查询得到的结果吧!
可以用select for update
谢谢这位兄弟,不过我这个不需要查询,因为原始数据是这个任务前一个小时同步过来的,所以A字段一直为空的。这个SQL的作用就是用另外一个接口的数据把这个表的A字段补充完整。
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){
}