证明一个操作的一致性读过程是以自己开始执行的时间为准回滚的不是以该操作所在的事务开始的时间为准回滚的

证明一个操作的一致性读过程是以自己开始执行的时间为准回滚的不是以该操作所在的事务开始的时间为准回滚的


初始条件:

SQL〉select * from test;

ID   NAME

---   -----------

1      a

2      b

3      c

开始实验:

会话1:

SQL〉set  time on

10:22:22   SQL〉update  test set  name=‘time’  where  id=1;//按时间顺序为第二个操作

已更新1行

10:24:30   SQL〉select * from test;//按时间顺序为第四个操作

ID   NAME

---   -----------

1      time

2      b

3      charge


10:25:30   SQL〉update  test set  name=‘goon’  where  name=‘charge’;//按时间顺序为第五个操作

已更新1行


10:26:30   SQL〉select * from test;//按时间顺序为第六个操作

ID   NAME

---   -----------

1      time

2      b

3      goon



会话2:

SQL〉set  time on

10:20:10   SQL〉update  test set  name=‘charge’  where  id=3;//按时间顺序为第一个操作

已更新1行

10:23:25   SQL〉commit; //按时间顺序为第三个操作

已提交


实验说明:

select操作(即读操作)开始执行时,它会以自己开始执行的时间SCN为准对它所要操作的表的所有数据内容进行一次一致性读模式的读取过程来回滚以获得select操作开始执行时的那一刻表的内容,接着再根据过滤条件(即where后的限制条件)过滤出select语句的结果,最后将这些结果显示在屏幕上。

DML操作(即写操作)开始执行时,它也会以自己开始执行的时间SCN为准对它所要操作的表的所有数据内容进行一次一致性读模式的读取过程来回滚以获得DML操作开始执行时的那一刻表的内容,接着再根据过滤条件(即where后的限制条件)过滤出DML操作的所要操作的那些数据行,最后DML操作根据这些数据行的地址以当前读模式找到在buffer cache上的相关数据行,对它们进行修改操作。

select操作(即读操作)和DML操作(即写操作)两个操作有一个共同点就是都有一个一致性读模式的读取过程,而DML操作(即写操作)还有一个当前读模式的修改过程。

回到本实验,假设一个DML操作的一致性读过程是以该操作所在的事务开始的时间为准回滚的,那么按时间顺序为第五个的操作(即update  test set  name=‘goon’  where  name=‘charge’)的一致性读过程是以它所在的事务开始的时间,即按时间顺序为第二个的操作( update  test set  name=‘time’  where  id=1)的/时间(10:22:22为准进行回滚的,这样回滚后对按时间顺序为第五个的操作来说,它看到表test内容如下:

ID   NAME

---   -----------

1      a

2      b

3      c

这样,它就发现表test的name字段不存在值为charge的,那 按时间顺序为第五个的操作的执行结果应该为未选定行才对,不是 已更新1行

而假设一个DML操作的一致性读过程是以自己开始执行的时间为准回滚的不是以该操作所在的事务开始的时间为准回滚的,就能说明本实验的结果了。具体过程如下:

按时间顺序为第五个的操作(即update  test set  name=‘goon’  where  name=‘charge’)的一致性读过程是以自己开始执行的时间,即10:25:30为准进行回滚的,这样回滚后对按时间顺序为第五个的操作来说,它看到表test内容如下:

ID   NAME

---   -----------

1      time

2      b

3      charge

这样,它就发现表test的name字段存在值为charge的,那 按时间顺序为第五个的操作根据该数据行的地址以 当前读模式找到在buffer cache上的相关数据行,对它进行了修改,执行结果故而为 已更新1行

注释:

假设还有个会话3在10:25:00时,update  test set  name=‘holy’  where  id=2,但是之后一直不提交,这样的话,按时间顺序为第五个的操作执行一致性读过程后,看到的表test内容里id=2的那一行的name还是为b,不是holy,因为一致性读时,读取的是undo块中提交的记录,而不会读取未提交的记录的。

=======================================================================================================

原理版:


会话1:

SQL〉set  time on

会话2:

SQL〉set  time on

10:20:10   SQL〉update  test set  name=‘charge’  where  id=3;//按时间顺序为第一个操作

已更新1行


10:22:22   SQL〉update  test set  name=‘time’  where  id=1;//按时间顺序为第二个操作

已更新1行

会话2:

10:23:25   SQL〉commit; //按时间顺序为第三个操作

已提交



10:24:30   SQL〉select * from test;//按时间顺序为第四个操作

ID   NAME

---   -----------

1      time

2      b

3      charge


10:25:30   SQL〉update  test set  name=‘goon’  where  name=‘charge’;//按时间顺序为第五个操作

已更新1行


10:26:30   SQL〉select * from test;//按时间顺序为第六个操作

ID   NAME

---   -----------

1      time

2      b

3      goon






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值