Oracle数据库连接ResultSet_TYPE_SENSITIVE和ResultSet_TYPE_INSENSITIVE的实现原理
2012-02-22 23:12
357 查看
JDBC2.0后提出了三种不同的cursor类型,用户代码可以在创建Statement指定cursor类型,如下:
Statement createStatement( int resultSetType, int resultSetConcurrency)
cursor类型
ResultSet.TYPE_FORWARD_ONLY
默认的cursor类型,仅仅支持向前forward,不支持backforward,random,last,first操作,类似单向链表。
TYPE_FORWARD_ONLY类型通常是效率最高最快的cursor类型
ResultSet.TYPE_SCROLL_INSENSITIVE
支持backforward,random,last,first操作,对其它数据session对选择数据做出的更改是不敏感,不可见的。
ResultSet.TYPE_SCROLL_SENSITIVE
支持backforward,random,last,first操作,对其它数据session对选择数据做出的更改是敏感,可见的。
分析
众所周知,JDBC对数据库进行数据查询时,数据库会创建查询结果的cache和cursor。而数据库的cursor是不支持backforward,random,last,first操作,仅仅只支持向前forward。那么TYPE_SCROLL_INSENSITIVE是如何实现支持backforward,random,last,first的呢?很简单,TYPE_SCROLL_INSENSITIVE的Statement查询把所有fetch的记录都缓存到JVM的Resultset对象内,如果有10个记录,直接跳到最后记录,TYPE_SCROLL_INSENSITIVE方式下把fetch所有记录到jvm端,并缓存下来,再进行random就是在数据库数组里面进行的。这也是TYPE_FORWARD_ONLY类型通常是效率最高最快的cursor类型原因,如果要做一些复杂的功能,必然是要牺牲一些效率的。
那么为什么TYPE_SCROLL_INSENSITIVE对选择数据做出的更改是不敏感,不可见的呢?前面提到,JDBC对数据库进行数据查询时,数据库会创建查询结果的cache和cursor,如下面sql:
select name,id from foo
用jdbc执行上面的sql语句时,数据库会把foo表所有记录的name和id字段缓存到cache中,之后cache和真正的数据库数据文件没有任何联系了,foo表发生的改变在查询完成后不会自动同步到cache上去,因此TYPE_SCROLL_INSENSITIVE对选择数据做出的更改是不敏感,不可见。
那么TYPE_SCROLL_SENSITIVE是怎么做到其它数据session对选择数据做出的更改是敏感,可见的。上面的sql语句用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对应那行记录并没有真正从数据库文件中抹去,一般是可以再次取到记录的。
总结
TYPE_FORWARD_ONLY类型通常是效率最高最快的cursor类型,也是最常用的选择。
TYPE_SCROLL_INSENSITIVE需要在jvm中cache所有fetch到的记录实体,在大量记录集返回时慎用。
TYPE_SCROLL_SENSITIVE在jvm中cache所有fetch到的记录rowid,需要进行二次查询,效率最低,开销最大
Statement createStatement( int resultSetType, int resultSetConcurrency)
cursor类型
ResultSet.TYPE_FORWARD_ONLY
默认的cursor类型,仅仅支持向前forward,不支持backforward,random,last,first操作,类似单向链表。
TYPE_FORWARD_ONLY类型通常是效率最高最快的cursor类型
ResultSet.TYPE_SCROLL_INSENSITIVE
支持backforward,random,last,first操作,对其它数据session对选择数据做出的更改是不敏感,不可见的。
ResultSet.TYPE_SCROLL_SENSITIVE
支持backforward,random,last,first操作,对其它数据session对选择数据做出的更改是敏感,可见的。
分析
众所周知,JDBC对数据库进行数据查询时,数据库会创建查询结果的cache和cursor。而数据库的cursor是不支持backforward,random,last,first操作,仅仅只支持向前forward。那么TYPE_SCROLL_INSENSITIVE是如何实现支持backforward,random,last,first的呢?很简单,TYPE_SCROLL_INSENSITIVE的Statement查询把所有fetch的记录都缓存到JVM的Resultset对象内,如果有10个记录,直接跳到最后记录,TYPE_SCROLL_INSENSITIVE方式下把fetch所有记录到jvm端,并缓存下来,再进行random就是在数据库数组里面进行的。这也是TYPE_FORWARD_ONLY类型通常是效率最高最快的cursor类型原因,如果要做一些复杂的功能,必然是要牺牲一些效率的。
那么为什么TYPE_SCROLL_INSENSITIVE对选择数据做出的更改是不敏感,不可见的呢?前面提到,JDBC对数据库进行数据查询时,数据库会创建查询结果的cache和cursor,如下面sql:
select name,id from foo
用jdbc执行上面的sql语句时,数据库会把foo表所有记录的name和id字段缓存到cache中,之后cache和真正的数据库数据文件没有任何联系了,foo表发生的改变在查询完成后不会自动同步到cache上去,因此TYPE_SCROLL_INSENSITIVE对选择数据做出的更改是不敏感,不可见。
那么TYPE_SCROLL_SENSITIVE是怎么做到其它数据session对选择数据做出的更改是敏感,可见的。上面的sql语句用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对应那行记录并没有真正从数据库文件中抹去,一般是可以再次取到记录的。
总结
TYPE_FORWARD_ONLY类型通常是效率最高最快的cursor类型,也是最常用的选择。
TYPE_SCROLL_INSENSITIVE需要在jvm中cache所有fetch到的记录实体,在大量记录集返回时慎用。
TYPE_SCROLL_SENSITIVE在jvm中cache所有fetch到的记录rowid,需要进行二次查询,效率最低,开销最大
相关文章推荐
- Study-Hard-数据库连接及实现内部原理(上)
- 关于oracle数据库分页的原理及实现
- WebSocket原理、为什么可以实现持久连接?
- 【Android开发】如何实现android和服务器长连接呢?推送消息的原理
- WebSocket 是什么原理?为什么可以实现持久连接
- .Net连接Oracle数据库的实现代码
- Java使用OCI驱动连接Oracle数据库实现方法
- WebSocket 是什么原理?为什么可以实现持久连接?
- (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
- ResultSet.TYPE_SCROLL_SENSITIVE到底发生了什么?
- JDBC连接oracle数据库,并实现批量插入
- 【Android开发】如何实现android和服务器长连接呢?推送消息的原理
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论 SignalR 简单示例 通过三个DEMO学会SignalR的三种实现方式 SignalR推送框架两个项目永久连接通讯使用 SignalR 集线器简单实例2 用SignalR创建实时永久长连接异步网络应用程序
- ResultSet.TYPE_SCROLL_SENSITIVE
- 在Oracle数据库实现自动断开空闲连接
- WebSocket 是什么原理?为什么可以实现持久连接?
- WebSocket 是什么原理?为什么可以实现持久连接?
- C#实现远程连接ORACLE数据库的方法
- 题注Oracle数据库的网络连接原理
- WebSocket 是什么原理?为什么可以实现持久连接