Posted on 2010-01-03 23:57
leekiang 閱讀(973)
評論(0) 編輯 收藏 所屬分類:
jdbc、事務、并發
resultSetType
的可選值有:
ResultSet.TYPE_FORWARD_ONLY
、ResultSet.TYPE_SCROLL_INSENSITIVE
、ResultSet.TYPE_SCROLL_SENSITIVE
1)
TYPE_FORWARD_ONLY是默認值,
僅支持結果集forward
,不支持滾動,也不是
SENSITIVE的
2)
ResultSet.TYPE_SCROLL_INSENSITIVE,
支持結果集backforward ,last
,first
等操作,對其它session對數據庫中數據做出的更改是不敏感的
原因:JDBC對數據庫進行數據查詢executeQuery時,數據庫會創建查詢結果的cache和cursor,如下面sql:
??? select name,id from foo
???
用jdbc執行上面的sql語句時,數據庫會把foo表所有記錄的name和id字段緩存到cache中,之后cache和真正的數據庫數據文件沒有任何聯系了,foo表發生的改變在查詢完成后不會自動同步到cache上去,因此TYPE_SCROLL_INSENSITIVE對選擇數據做出的更改是不敏
感,不可見。
3)ResultSet.TYPE_SCROLL_SENSITIVE
支持結果集backforward
,last
,first
等操作,對其它session對數據庫中數據做出的更改是敏感的,即其他session
修改了數據庫中的數據,會反映到本結果集中
上面的select name,id from foo語句用TYPE_SCROLL_SENSITIVE的Statement來執行,會轉化成以下的sql語句:
??? select rowid from foo
??? 數據庫這時候是把foo表所有記錄的rowid緩存到cache中,用戶代碼在fetch記錄時,再繼續做以下查詢:
??? select name,id from foo where rowid=?
???
因此這時候發生的查詢是實時從真正的數據庫數據文件中取,因此對期間發生的數據更改是可見的,敏感的。但是這種可見性僅限于update操作,而
insert和delete同樣是不可見的。因為如果查詢發生在insert之前,insert生成的rowid并不會反應在cache中的rowid結果集上。在一個記錄的rowid已經緩存到cache中,這時候被刪除了,但一般數據庫的刪除是標記刪除,也就是說rowid對應那行記錄并沒有真正從數
據庫文件中抹去,一般是可以再次取到記錄的。
結論:是否SENSITIVE與fetchsize沒有什么關系。是否SENSITIVE是告訴數據庫如何作查詢的緩存。fetchsize是客戶端jdbc的設置。
另外oracle的fetchsize默認為10,
stmt.setFetchSize(0)時stmt.getFetchSize()=10
stmt.setFetchSize(1)時stmt.getFetchSize()=1
另外如果查詢的sql復雜時,我發現就算設為ResultSet.TYPE_SCROLL_SENSITIVE也不起作用,如
select t.*? from test t left join testp p on t.pid=p.id where p.title like '%國%',在運行中修改title的值,發現仍然可以取到。是否可以理解為SENSITIVE只對查詢的主表起作用。
摘自:
http://www.javaeye.com/topic/128636
http://www.javaeye.com/topic/560109
http://www.javaeye.com/topic/418604