转自:https://blog.csdn.net/axman/article/details/3984103

这个问题我在几年前说过,但今天再次从CSDN上看到有人问这个问题,可以看出,真正懂这个问题的人1%都不到。
我再次把这个问题写在这里,希望光临我的BLOG的人能真正了解它。

我们先来做一个例子,在例子中我用的是mysql-essential-5.1.30-win32版。

来跟我做以下几个命令:

mysql> create database axman;
mysql> use axman;
mysql> create table axmantest(
    -> id int(4) not null auto_increment primary key
    -> name varchar(20));

mysql> insert into axmantest (name) values ('axman')
mysql> insert into axmantest (name) values ('sager')
mysql> insert into axmantest (name) values ('p4');

OK,写一个测试程序:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class MainTest {
 public static void main(String[] args) throws Exception{
  
  Class.forName("org.gjt.mm.mysql.Driver");
  Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/axman?useUnicode=true&characterEncoding=UTF-8","root","password");
  Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
  ResultSet rs = stmt.executeQuery("select * from axmantest");
  System.out.println("请删除!");
  Thread.sleep(1000*20);
  while(rs.next()){
   System.out.println(rs.getString(1)+","+rs.getString(2));
  }
  rs.close();
  stmt.close();
  conn.close();
 }
}

先在刚才的MYSQL命令环境下输入命令:
select * from axmantest;
+----+-------+
| id | name  |
+----+-------+
|  1 | axman |
|  2 | sager |
|  3 | p4    |
+----+-------+
3 rows in set (0.00 sec)

delete from axmantest where id = 3;不要提交,敲好放在这儿,运行那个测试程序。看到“请删除”三个字立即切换到
Mysql命令环境下回车。
跟着:
select * from axmantest;
+----+-------+
| id | name  |
+----+-------+
|  1 | axman |
|  2 | sager |
+----+-------+
2 rows in set (0.00 sec)

回到测试程序,看看:
1,axman
2,sager
3,p4

我的个神啦,这哪叫结果集敏感啊?完全是INSENSITIVE嘛!

但是,这正是TYPE_SCROLL_SENSITIVE造成的。

对于TYPE_SCROLL_INSENSITIVE,一次查询的结果可能存在数据库端的内存缓冲中,也可以直接发送到JVM的内存中,
如果结果集很小,会直接发送到JVM层,然后被next定位,转换数据类型,显示,或者缓存在数据库内存中。总之
查询结果已经和数据库脱离,这时如果数据库记录被其它进程更新,则结果集无法得知,还是使用缓存的记录。

而对于TYPE_SCROLL_SENSITIVE,一次查询的结果并不是直接的记录被缓存下来,只是符合条件的记录的“原始ROWID”
被缓存了,这个原始ROWID并非特指ORACLE的ROWID,而是数据库底层定位记录的索引值。简单说
select * from axmantest操作的结果并不是
1,axman
2,sager
3,p4
这些内容被缓存了。而是类似rd_file_offset_0x111010101001这样的值被缓存了,然后next定位到这条记录时,
数据库会再次根据这个ROWID做底层操作:
select * from axmantest where rowid = rd_file_offset_0x111010101001;
简单说每next一次都会发生一次查询,这样可以保证next后操作到的是当前最新的数据。
对于更新操作,如果你先查询,然后数据被其它进程更新掉了,然后next到这条记录时肯定没有问题,会取出最新的
内容,但对于删除操作。因为数据库删除记录只是记录上做一个标记,不再被检索,但原来被缓存的ROWID还在,根据
它还可以通过数据库自己的底层操作正确地把数据提取出来,所以你看到的已经被手工删除的数据又被显示出来了。

同样插入操作因为查询的时候结果集中还没有要插入的操作,所以不可能缓存了它的ROWID,我们再次做这个例子,把
“请删除”修改成“请插入”(有些不好听),现在数据库中是两条记录,当运行程序看到“请插入”时立即插入,注意
我说的是往表中插入记录,不是插入别的。然后看一下运行结果还是两条记录。

如果有兴趣再试一下更新操作,你会看更新的结果会马上反映出来。

所以TYPE_SCROLL_SENSITIVE只能更新操作敏感,其它的插入操作和删除操作不会及时地反映到结果集中。

ResultSet.TYPE_SCROLL_SENSITIVE到底发生了什么?的更多相关文章

  1. ResultSet.TYPE_SCROLL_SENSITIVE问题(完全摘自他人)

    摘自CSDN博客 我们先来做一个例子,在例子中我用的是mysql-essential-5.1.30-win32版. 来跟我做以下几个命令: mysql> create database axma ...

  2. Js new到底发生了什么

    在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...

  3. JS中new到底发生了什么

    outline prototype 与 __proto__ function 与 object new 到底发生了什么 prototype 与 __proto__ 首先说下在JS中比较容易让人困惑的  ...

  4. 【原】老生常谈-从输入url到页面展示到底发生了什么

    刚开始写这篇文章还是挺纠结的,因为网上搜索“从输入url到页面展示到底发生了什么”,你可以搜到一大堆的资料.而且面试这道题基本是必考题,二月份面试的时候,虽然知道这个过程发生了什么,不过当面试官一步步 ...

  5. 一个完整的 Web 请求到底发生了什么

    阅读本文大概需要 7 分钟. 一.从输入一个网址开始 当我们在浏览器输入一个网址,然后按下回车,接下来浏览器显示了页面.网速好的话这之间可能就一秒,但在这一秒内到底发生了什么? 本文主要内容是试图记录 ...

  6. 经典面试题:从 URL 输入到页面展现到底发生什么?

    前言 打开浏览器从输入网址到网页呈现在大家面前,背后到底发生了什么?经历怎么样的一个过程?先给大家来张总体流程图,具体步骤请看下文分解! 本文首发地址为GitHub 博客,写文章不易,请多多支持与关注 ...

  7. 从URL输入到页面展现到底发生什么

    前言 打开浏览器从输入网址到网页呈现在大家面前,背后到底发生了什么?经历怎么样的一个过程?先给大家来张总体流程图,具体步骤请看下文分解!   从URL输入到页面展现 总体来说分为以下几个过程: DNS ...

  8. 【转】老生常谈-从输入url到页面展示到底发生了什么

    今天看到了一篇很详细地解释了从输入url到页面展示过程的文章,好文章不能错过,所以转到自己这里来了. 原文地址:老生常谈-从输入url到页面展示到底发生了什么 以下为原文: 刚开始写这篇文章还是挺纠结 ...

  9. (转)老生常谈-从输入url到页面展示到底发生了什么

    刚开始写这篇文章还是挺纠结的,因为网上搜索"从输入url到页面展示到底发生了什么",你可以搜到一大堆的资料.而且面试这道题基本是必考题,二月份面试的时候,虽然知道这个过程发生了什么 ...

随机推荐

  1. MySQL MVVC

    什么是MVVC? MVVC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Contr ...

  2. session.资料

    1. HttpSessionListener https://www.cnblogs.com/diewufeixian/p/4221747.html 2. 3. 4. 5.

  3. Jenkins的安装和使用

    1.可以参考W3C----https://www.w3cschool.cn/jenkins/jenkins-5h3228n2.html 两种方式安装Jenkins a.安装包 b.Jenkins.wa ...

  4. UVA-11294 Wedding (2-SAT)

    题目大意:一张长桌,n对夫妻,编号为0~n,这些人要坐在长桌两侧,每对夫妻不能坐在同一侧.其中,有2*m个人相互讨厌,编号为0的夫妻中的妻子不愿意让对面那一侧中有两个相互吵过架的人,找一种排座位方案. ...

  5. day19 Models补充+缓存+信号+序列化+分析抽屉页面

    参考链接: http://www.cnblogs.com/wupeiqi/articles/5237704.html http://www.cnblogs.com/wupeiqi/articles/5 ...

  6. 【Error】2003 - Can't connect to MySQL server on 'localhost' (10038)

    此错误主要是连接MySQL地址的地址搞错了. 可以看下 MySQL 的配置文件 /etc/mysql/my.cnf, 其中绑定的本地地址如下: bind-address=127.0.0.1 将其注释掉 ...

  7. 【Python】偏函数

    此文转载自廖雪峰. Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function).要注意,这里的偏函数和数学意义上的偏函数不一样. 在介绍函数参数的 ...

  8. 实现Callable接口创建线程

    创建执行线程有四种方式: 实现implements接口创建线程 继承Thread类创建线程 实现Callable接口,通过FutureTask包装器来创建线程 使用线程池创建线程 下面介绍通过实现Ca ...

  9. commons-fileupload实现上传进度条的显示

    本文将使用   apache fileupload   ,spring MVC   jquery 实现一个带进度条的多文件上传, 由于fileupload 的局限,暂不能实现每个上传文件都显示进度条, ...

  10. redis在.net架构中的应用(1)--利用servicestack连接redis

    引言:作为少有的.net架构下的大型网站,stackoverflow曾发表了一篇文章,介绍了其技术体系,原文链接http://highscalability.com/blog/2011/3/3/sta ...