oracle小知識點2--一致性讀中的重啟動更新
以下三個問題,個人覺得很有趣,如果沒有了解oracle的重啟動更新,可能會對查詢結果感到懷疑~
--oracle version:11.2.0.2.0
--問題一:
----建測試表
create table scott.test01
as select 1 a from dual
union all select 2 from dual
union all select 3 from dual;
----查詢結果
select * from scott.test01;
/*
A
1
2
3
*/
----session 1執行:
update scott.test01
set a=3
where a<3;
----session 2執行:
update scott.test01
set a=2
where a=3;
----session 1執行:
commit;
----session 2執行:
commit;
----session 1執行:
select * from scott.test01;
----此處session 1的查詢結果是
/*
3
3
2
*/
問題一的結果,說明session 1的update沒有影響到session 2的update
session 1 update後,根據一致性讀,session 2看到的還是沒有更新過的結果.session 2做update操作鎖定的行與session 1 update時鎖定的行不相同.
session 1 commit提交要更新的行,並釋放鎖,session 2 commit提交要更新的行,並釋放鎖,相互之間不影響.
--問題二:
----建測試表
drop table scott.test01 purge;
create table scott.test01
as select 1 a from dual
union all select 2 from dual
union all select 3 from dual;
----查詢結果
select * from scott.test01;
/*
A
1
2
3
*/
----session 1執行:
update scott.test01
set a=1
where a>1;
----session 2執行:
update scott.test01
set a=4
where a<3;
----session 1執行:
commit;
----session 2執行:
commit;
----session 1執行:
select * from scott.test01;
----此處session 1的查詢結果是什麼?
/*
4
4
4
*/
問題二的結果,說明session 1的update影響到session 2的update
session 1 update後,根據一致性讀,session 2看到的還是沒有更新過的結果.session 2做update操作鎖定行時,與session 1 update時鎖定的行在a=2這一行是相同的,此時session 2會被阻塞,等待session 1 commit或rollback.
session 1 commit提交要更新的行,並釋放鎖.
重點來了,由於session 1提交後,session 2要鎖定的行對應的where a<3中a的值有變更,此時oralce內部會回滾更新,並重啟動更新,因為原本a=3被session 1更新為a=1,所以在重啟動
更新時也會被where a<3所包含,最後三條記錄全部被更新了.
--問題三:
----建測試表
drop table scott.test01 purge;
create table scott.test01
as select 1 a from dual
union all select 2 from dual
union all select 3 from dual;
----查詢結果
select * from scott.test01;
/*
A
1
2
3
*/
----session 1執行:
update scott.test01
set a=2
where a>1;
----session 2執行:
update scott.test01
set a=4
where a<3;
----session 1執行:
commit;
----session 2執行:
commit;
----session 1:
select * from scott.test01;
----此處session 1的查詢結果是什麼?
/*
4
4
2
*/
問題三的結果,說明session 1的update沒有影響到session 2的update
session 1 update後,根據一致性讀,session 2看到的還是沒有更新過的結果.session 2做update操作鎖定行時,與session 1 update時鎖定的行在a=2這一行是相同的,此時session 2會被阻塞,等待session 1 commit或rollback.
session 1 commit提交要更新的行,並釋放鎖.
由於session 1提交後,session 2要鎖定的行對應的where a<3中a有更新,但a=2的值沒有變更,此時oralce不需要回滾更新,所以更新之前鎖定的兩行,原本a=3的行雖然在session 1中已經被更新為2滿足where a<3,但由於沒有重啟動更新,就不會更新這一行.
--備註:
這樣看來,重啟動更新 依賴於會話之間的行鎖阻塞及where條件中的值變更.在計算結果的時候,要結合rowid和where條件一起比較容易判斷.重啟動更新可以透過觸發器撲捉到.
--oracle version:11.2.0.2.0
--問題一:
----建測試表
create table scott.test01
as select 1 a from dual
union all select 2 from dual
union all select 3 from dual;
----查詢結果
select * from scott.test01;
/*
A
1
2
3
*/
----session 1執行:
update scott.test01
set a=3
where a<3;
----session 2執行:
update scott.test01
set a=2
where a=3;
----session 1執行:
commit;
----session 2執行:
commit;
----session 1執行:
select * from scott.test01;
----此處session 1的查詢結果是
/*
3
3
2
*/
問題一的結果,說明session 1的update沒有影響到session 2的update
session 1 update後,根據一致性讀,session 2看到的還是沒有更新過的結果.session 2做update操作鎖定的行與session 1 update時鎖定的行不相同.
session 1 commit提交要更新的行,並釋放鎖,session 2 commit提交要更新的行,並釋放鎖,相互之間不影響.
--問題二:
----建測試表
drop table scott.test01 purge;
create table scott.test01
as select 1 a from dual
union all select 2 from dual
union all select 3 from dual;
----查詢結果
select * from scott.test01;
/*
A
1
2
3
*/
----session 1執行:
update scott.test01
set a=1
where a>1;
----session 2執行:
update scott.test01
set a=4
where a<3;
----session 1執行:
commit;
----session 2執行:
commit;
----session 1執行:
select * from scott.test01;
----此處session 1的查詢結果是什麼?
/*
4
4
4
*/
問題二的結果,說明session 1的update影響到session 2的update
session 1 update後,根據一致性讀,session 2看到的還是沒有更新過的結果.session 2做update操作鎖定行時,與session 1 update時鎖定的行在a=2這一行是相同的,此時session 2會被阻塞,等待session 1 commit或rollback.
session 1 commit提交要更新的行,並釋放鎖.
重點來了,由於session 1提交後,session 2要鎖定的行對應的where a<3中a的值有變更,此時oralce內部會回滾更新,並重啟動更新,因為原本a=3被session 1更新為a=1,所以在重啟動
更新時也會被where a<3所包含,最後三條記錄全部被更新了.
--問題三:
----建測試表
drop table scott.test01 purge;
create table scott.test01
as select 1 a from dual
union all select 2 from dual
union all select 3 from dual;
----查詢結果
select * from scott.test01;
/*
A
1
2
3
*/
----session 1執行:
update scott.test01
set a=2
where a>1;
----session 2執行:
update scott.test01
set a=4
where a<3;
----session 1執行:
commit;
----session 2執行:
commit;
----session 1:
select * from scott.test01;
----此處session 1的查詢結果是什麼?
/*
4
4
2
*/
問題三的結果,說明session 1的update沒有影響到session 2的update
session 1 update後,根據一致性讀,session 2看到的還是沒有更新過的結果.session 2做update操作鎖定行時,與session 1 update時鎖定的行在a=2這一行是相同的,此時session 2會被阻塞,等待session 1 commit或rollback.
session 1 commit提交要更新的行,並釋放鎖.
由於session 1提交後,session 2要鎖定的行對應的where a<3中a有更新,但a=2的值沒有變更,此時oralce不需要回滾更新,所以更新之前鎖定的兩行,原本a=3的行雖然在session 1中已經被更新為2滿足where a<3,但由於沒有重啟動更新,就不會更新這一行.
--備註:
這樣看來,重啟動更新 依賴於會話之間的行鎖阻塞及where條件中的值變更.在計算結果的時候,要結合rowid和where條件一起比較容易判斷.重啟動更新可以透過觸發器撲捉到.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28539951/viewspace-1705502/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- iOS--小知識點(持續更新)iOS
- oracle事務知識點小結Oracle
- oracle小知識點9--cluvfyOracle
- oracle 歸檔日誌的小知識點Oracle
- easyui中的combobox小知識點~~UI
- Python 中不易懂的小知識點Python
- Oracle_day1(小知識點)Oracle
- VEEAM的小知識點
- C++知識點 —— 整合(持續更新中)C++
- java小知識點Java
- js小知識點JS
- 小知識點1
- 前端小知識點前端
- mongo 小知識點Go
- javascript小知識點JavaScript
- PHP小知識點PHP
- java 重寫知識點Java
- 記錄的小知識點
- oracle小知識點1--varchar2的長度Oracle
- 浮點數小知識點
- Mybatis中的小知識MyBatis
- Oracle知識小記Oracle
- 前端知識點(持續更新)前端
- centos系列的啟動流程及基礎知識點CentOS
- 【JAVA】- 知識點小結Java
- promise知識點小結Promise
- CSS小知識點一CSS
- HTTP知識點小結HTTP
- makefile 知識點小結
- ElasticSearch知識點小記Elasticsearch
- HTTP和AJAX重點知識HTTP
- 總結的小知識點(一)
- Sqlserver關於統計資訊自動建立自動更新的知識點SQLServer
- Python中關於Thread的一點小知識Pythonthread
- 專攻知識小點——回顧JavaWeb中的servlet(二)JavaWebServlet
- oracle小知識點16-診斷事件diagnostic eventsOracle事件
- oracle小知識點7--索引的unusable,disable,invisibleOracle索引
- 關於Java兩點需要更新的知識Java