下面是转发的一个帖子,原贴也有解答....恰好和这个相似,请高人帮忙解释一下最近调一个j2ee的系统
数据库是oracle9i
前台用ejb通过jdbc调用
可是在系统运行中出现数据库死锁的现象。
死锁部分代码大致如下:preparedstatement = connection.prepareStatement("update USERINFO set USER_ID = ?,NAME = ?,PASSWORD = ?,TIER = ?,REALNAME = ?,PHONE = ?,EMAIL = ?,ADDRESS = ?,FAX = ?,PWDQUESTION = ?,PWDANSWER = ?,ISWRITING = ?,REGISTTIME = ?,LASTLOGINTIME = ?,LOGCOUNTS = ? where USER_ID = ?");
if(userId != null)
preparedstatement.setString(1, userId);
else
preparedstatement.setNull(1, 12);
if(name != null)
preparedstatement.setString(2, name);
else
preparedstatement.setNull(2, 12);
if(password != null)
preparedstatement.setString(3, password);
else
preparedstatement.setNull(3, 12);
if(tier != null)
preparedstatement.setString(4, tier);
else
preparedstatement.setNull(4, 12);
if(realname != null)
preparedstatement.setString(5, realname);
else
preparedstatement.setNull(5, 12);
if(phone != null)
preparedstatement.setString(6, phone);
else
preparedstatement.setNull(6, 12);
if(email != null)
preparedstatement.setString(7, email);
else
preparedstatement.setNull(7, 12);
if(address != null)
preparedstatement.setString(8, address);
else
preparedstatement.setNull(8, 12);
if(fax != null)
preparedstatement.setString(9, fax);
else
preparedstatement.setNull(9, 12);
if(pwdquestion != null)
preparedstatement.setString(10, pwdquestion);
else
preparedstatement.setNull(10, 12);
if(pwdanswer != null)
preparedstatement.setString(11, pwdanswer);
else
preparedstatement.setNull(11, 12);
if(iswriting != null)
preparedstatement.setString(12, iswriting);
else
preparedstatement.setNull(12, 12);
if(registtime != null)
preparedstatement.setTimestamp(13, new Timestamp(registtime.getTime()));
else
preparedstatement.setNull(13, 93);
if(lastlogintime != null)
preparedstatement.setTimestamp(14, new Timestamp(lastlogintime.getTime()));
else
preparedstatement.setNull(14, 93);
if(logcounts != null)
preparedstatement.setString(15, logcounts);
else
preparedstatement.setNull(15, 12);
preparedstatement.setString(16, userId);
System.out.println("to execute");
int i = preparedstatement.executeUpdate();
System.out.println("execute end");
if(i == 0)
throw new EJBException("Storing row failed.! ");
System.out.println("storeRow"); 
在执行preparedstatement.executeUpdate()这句话的时候出现死锁现象,通过客户端查看数据库,确实有锁。
但是,把上面的代码改为
preparedstatement = connection.prepareStatement("update USERINFO set USER_ID = "+userId+",NAME = "+name+",PASSWORD = "+password+",TIER = "+tier+",REALNAME = "+realname+",PHONE = "+phone+",EMAIL = "+email+",ADDRESS = "+address+",FAX = "+fax+",PWDQUESTION = "+pwdquestion+",PWDANSWER = "+pwdanswer+",ISWRITING = "+iswriting+",REGISTTIME = "+new Timestamp(registtime.getTime())+",LASTLOGINTIME = "+new Timestamp(lastlogintime.getTime())+",LOGCOUNTS = "+logcounts+" where USER_ID = "+userId)
后,参数不通过set***函数,而是直接以字符串连接的形式传给preparedstatement,系统再运行时候就不再出现死锁。出现死锁可能与事务等相关,现在我也无法确定原因,只能确定到是这里出现了死锁。
不明白是通过set***函数和直接连接字符串方式确定sql语句的参数,这两种方式有什么区别?以前一直认为只是在性能上有区别。
难道这两种方式加锁的范围或者级别不一样么