MDA/MDD/TDD/DDD/DDDDDDD
posts - 536, comments - 111, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
resultSetType 的可选值有: ResultSet.TYPE_FORWARD_ONLY ResultSet.TYPE_SCROLL_INSENSITIVEResultSet.TYPE_SCROLL_SENSITIVE
1)
TYPE_FORWARD_ONLY是默认值, 仅支持结果集forward ,不支持滚动,也不是 SENSITIVE的
2)
ResultSet.TYPE_SCROLL_INSENSITIVE,
支持结果集backforwardlastfirst 等操作,对其它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
支持结果集backforwardlastfirst 等操作,对其它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()=1
0
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

只有注册用户登录后才能发表评论。


网站导航: