有一个交易信息表,bbl_jy ,这个方法的目标是统计每个交易的产品被访问了多少次,可是用户每点击一点,一进到这个方法里面就死锁,程序走到,con.commit()这一步,就开始等待了,我在oracle里在查了一下,有死锁存在,可是把死锁全部杀完了以后,又重新刷一下页面,调用这个方法,结果还是死锁,不知原因何里,这个交易信息表是并发访问的,前台用户可以访问,后台的编辑人员也要访问,获取的连接用的是连接池,数据库是oracle10g,请各位大侠帮忙看看,其它方法操作这张表的时候(insert,update,del)都加了事务,我在想,如果把oracle服务器重新起一下,应该会...但我这个方法在别的表里面用,一点问题都没有,我现在怀疑是不是这张交易表被别的方法调用产生的死锁,期待中...............
public synchronized  boolean  updateSpeciyfJyNumberCount(String id)
{
Connection con = this.getConn();
Statement st = null;
PreparedStatement pst = null;
ResultSet rt = null;
int count = 0;
int countEx=0;
try {
if (con != null && id!= null) 
{
if(id != null && !"".equals(id))
id=id.replaceAll("\\s", "");

con.setAutoCommit(false);
String sql = "update BBL_JY set LOOKTIMES=LOOKTIMES+1  where JYId=?";
pst = con.prepareStatement(sql);
pst.setString(1, id);
count = pst.executeUpdate();
con.commit();
con.setAutoCommit(true);
} else {
throw new Exception("数据库没有连接");
}

} catch (Exception t) {
try{
if(con != null)
{
con.rollback();
con.setAutoCommit(true);
}

}catch(Exception tt)
{
t.printStackTrace();
} t.printStackTrace();

} finally {
if (dbc != null) {
dbc.freeConnection("idb", con);
}
this.closeConn(st, pst, rt);
} if (count > 0) {
return true;
} else {
return false;
}
}

解决方案 »

  1.   

    这应该不是死锁,而是锁等待。如果是死锁,oracle是能检测到并终止其中一个session。你可以查v$locked_object,看看都是谁锁了那张表。
      

  2.   

    我怀疑程序里所有对这个表操作方法里,有某个在update/delete后没有提交。
    因为你用的是连接池,所以即使是同一个Web session操作中可能也用到多个connection.产生lock wait.
    能否加入一段测试代码?   String sql = "select 1 from BBL_JY where JYId=? for update nowait";
       try pst = con.prepareStatement(sql);
    pst.setString(1, id);
    try{ Recordset rs = pst.executeQuery();
    //然后是原来的Update语句
    }
    catch(Exception tt)
    {//说明这笔记录有其他DB Connection在lock住还没提交,你在这里就可以知道“现在有别的方法正在Lock这笔纪录”
    }另外,我觉得你的异常处理有些问题,捕捉到异常以后,怎么可以仅仅 t.printStackTrace();呢?
    抛出或者用log纪录下来。否则出什么问题都不知道另外我不知道为什么这个方法要synchronized  呢?没必要吧