JDBC的連線引數的設定導致rowid自動新增到sql

yy418408247發表於2016-05-26

1,問題描述:
在資料庫後臺經常捕獲到如下的sql:
select rowid, * From PrpDcompany Where ComCode =:1
而實際上我們系統只觸發瞭如下的sql:
select * From PrpDcompany Where ComCode =:1

從weblogic到oracle的整個過程中,有一個步驟自動新增了rowid到sql中;

2,問題原因解釋:
經多方瞭解,JDBC的連線屬性的設定可能導致rowid的自動新增;
我們現有程式中存在如下的JDBC屬性設定:
preparedStatement = con.prepareStatement(strSql,ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

屬性ResultSet.TYPE_SCROLL_INSENSITIVE表示資料從資料庫讀取出來後放到client端的resultset後,不再關心資料庫中的資料是否變化了,即使變化了
他也不會去同步;

ResultSet.CONCUR_UPDATABLE--該屬性表示取出來的資料可能需要被更新回資料庫;由於可能需要被更新回去,
所以執行select的時候會把rowid自動新增進來,這個rowid用來唯一標識一條記錄;

屬性ResultSet.TYPE_SCROLL_INSENSITIVE和ResultSet.CONCUR_UPDATABLE共同使用本來就是矛盾的,一個不再關心資料庫裡的資料了,
一個還是需要往回更新資料;

3,問題重現
根據以上的理論,設計一個java,並在後臺跟蹤,結果是:
屬性ResultSet.TYPE_SCROLL_INSENSITIVE和ResultSet.CONCUR_UPDATABLE共同使用的場合,會出現:
PARSE ERROR #7:len=51 dep=0 uid=90 oct=3 lid=90 tim=8485473208992 err=936
select rowid, * From PrpDcompany Where ComCode =:1


java 檔案如下:

package com.sinosoft.accfee.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;

public class Test1 {
public static void main(String[] args) throws Exception {
//定義驅動器地址
String url="jdbc:oracle:thin:@10.0.13.40:1521:perfdb";
//下載驅動器
Class.forName("oracle.jdbc.driver.OracleDriver");
//與驅動器建立連線
Connection connection=DriverManager.getConnection(url,"ccic","ccic$1211");
Thread.sleep(120*1000);
try {
for(int i=0;i<1000000;i++){
Statement stmt=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);


ResultSet resultset = (ResultSet)stmt.executeQuery("Select comtype From prpdcompany Where comcode = '11010001'");

while(resultset.next()){
System.out.println(resultset.getString(1));
//..........
}
//關閉開啟的連線、包容器、記錄集、
resultset.close();

ResultSet resultset1 = (ResultSet)stmt.executeQuery("Select * From prpdcompany Where comcode = '11010001'");

while(resultset1.next()){
System.out.println(resultset1.getString(1));
//..........
}
//關閉開啟的連線、包容器、記錄集、
resultset1.close();

stmt.close();
Thread.sleep(1000);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
connection.close();
}
}
}

trace 如下:

*** 2009-12-22 16:20:23.013
*** SERVICE NAME:(SYS$USERS) 2009-12-22 16:20:23.007
*** SESSION ID:(2153.8127) 2009-12-22 16:20:23.007
=====================
PARSING IN CURSOR #1 len=65 dep=0 uid=90 oct=3 lid=90 tim=8563923159082 hv=1060576053 ad='f41bc160'
select rowid, comtype From prpdcompany Where comcode = :"SYS_B_0"
END OF STMT
PARSE #1:c=0,e=644,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=8563923159078
EXEC #1:c=0,e=1897,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,tim=8563923166667
FETCH #1:c=0,e=80,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=1,tim=8563923166842
STAT #1 id=1 cnt=1 pid=0 pos=1 obj=50329 op='TABLE ACCESS BY INDEX ROWID PRPDCOMPANY (cr=3 pr=0 pw=0 time=67 us)'
STAT #1 id=2 cnt=1 pid=1 pos=1 obj=50330 op='INDEX UNIQUE SCAN PK_PRPDCOMPANY (cr=2 pr=0 pw=0 time=33 us)'
=====================
PARSE ERROR #1:len=60 dep=0 uid=90 oct=3 lid=90 tim=8563923230414 err=936
select rowid, * From prpdcompany Where comcode = :"SYS_B_0"
=====================
PARSING IN CURSOR #1 len=52 dep=0 uid=90 oct=3 lid=90 tim=8563923244727 hv=1150625011 ad='af22b5c0'
Select * From prpdcompany Where comcode = :"SYS_B_0"
END OF STMT
PARSE #1:c=0,e=85,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=8563923244725
EXEC #1:c=0,e=35,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,tim=8563923244811
FETCH #1:c=0,e=56,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=1,tim=8563923245068
STAT #1 id=1 cnt=1 pid=0 pos=1 obj=50329 op='TABLE ACCESS BY INDEX ROWID PRPDCOMPANY (cr=3 pr=0 pw=0 time=30 us)'
STAT #1 id=2 cnt=1 pid=1 pos=1 obj=50330 op='INDEX UNIQUE SCAN PK_PRPDCOMPANY (cr=2 pr=0 pw=0 time=13 us)'

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29494175/viewspace-2107107/,如需轉載,請註明出處,否則將追究法律責任。

相關文章