開發業務系統時,是繞不開RDBMS(關係型資料庫)的。雖然現在誕生了各種NoSQL的資料庫,RDBMS在業務系統中的嚴謹和優勢依然無法取代。 近幾年大大小小的項目中,常用的三種RDBMS(SQLite,MySQL,Postgres)都有多次接觸過,一些使用心得記錄如下,供大家參考。 1. SQLit ...
1 事務的概念
事務是將資料庫從一種一致性狀態轉變為另外一種一致性狀態
2 事務的四個特征(ACID)
- 原子性(Atomicity):事務的所有執行要麼一起成功,要麼一起失敗
- 一致性(Consistency):事務將數據從一種一致性狀態轉為另外一種一致性狀態
- 隔離性(Isolation):事務中所有修改未提交的數據對其他事務是不可見的
- 持久性(Durability):事務一旦提交,數據就永久保存
2.1 DDL與原子性
DDL語句執行之前,會先自動執行一個commit,再執行DDL語句本身。
2.2 COMMIT_WAIT與持久性
oracle的持久性是依靠redo來保證的。一般情況下,commit執行時,只有數據對應的redo緩存寫入到redo線上重做日誌後,才會給客戶端返回commit成功的信息。
COMMIT_WAIT參數有三個值WAIT、NOWAIT和FORCE_WAIT。當COMMIT_WAIT設置為NOWAIT時,commit執行時資料庫無需等待redo緩存寫入到redo線上重做日誌,直接給客戶端返回commit成功的信息。但是,這樣子做,無法保證數據的持久性。因為此時commit成功,redo緩存並沒有寫入到redo線上重做日誌。如果此時資料庫突然關閉,這次修改的數據無法通過redo進行恢復。
3 分散式事務
有時候,我們會使用DBLINK聯合其他伺服器上的oracle資料庫執行一個事務。這種分散式事務,oracle是通過2PC(Two-Phase Commit Protocol,兩階段提交協議)實現事務的原子性的。2PC原理是oracle在處理分散式事務時,會指定一個資料庫作為協調者,這個協調者在提交事務時,會詢問各個資料庫是否做好提交。如果每個資料庫都回覆確定提交,協調者告訴各個資料庫進行提交。如果其他資料庫有回覆不可以提交,則協調者會讓各個資料庫進行回滾。
4 自治事務
當一個事務為自治事務時,這個事務的提交和回滾都不會影響父事務。例如,我們有如下一個自治事務的存儲過程(使用pragma autonomous_transaction聲明)
create or replace procedure Autonomous_Insert as
pragma autonomous_transaction;
begin
insert into bk_test values (2);
commit;
end;
我們執行如下SQL
begin
insert into bk_test values(1);
Autonomous_Insert;
rollback;
end;
查詢結果
可見,剛纔那段sql最後一個rollback,只回滾了數據為1的數據。Autonomous_Insert中的commit成功插入了數據2,卻沒有將父事務中的數據1進行commit。可見,Autonomous_Insert中的commit對於父事務是獨立提交的。
5 事務過程中oracle實例的變化
- 事務開始
- 在共用池中查找對應的已經編譯過的執行計劃。如果沒有找到,則生成執行計劃
- 在資料庫高速緩存中查找對應的數據塊,如果沒有找到,就從數據文件中讀取對應的數據塊,載入到資料庫高速緩存中
- 在資料庫高速緩存中修改對應的數據塊,這些塊就變成了臟塊。同時在redo緩存中生成redo日誌
- 當事務提交時,等待redo緩存中的對應的redo日誌全部寫入到線上重做日誌文件,寫入完成後返回提交成功信息
- 當發生checkpoint時,DBWn進程會將對應的臟塊寫入到數據文件中。寫入後CKPT進程更新數據文件和控制文件中的SCN信息