標籤:
淺談Oracle事務【轉載竹瀝半夏】
所謂事務,他是一個操作序列,這些操作要麼都執行,要麼都不執行,是一個不可分割的工作單元。通俗解釋就是事務是把很多事情當成一件事情來完成,也就是大家都在一條船上,要死一起死,要活一起活。
為什麼要引入事務?交易處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過將一組相關操作組合為一個要麼全部成功要麼全部失敗的單元,可以簡化錯誤恢複並使應用程式更加可靠。事務結束後,能保證資料庫資料的一致性。例如銀行轉賬,一個帳號扣錢,一個帳號增款,要麼都執行,要麼都不執行,不能只執行一條,否則會出現賬款錯誤。這樣我們就可以體會到事務的重要性了吧。其實在我們的生活中,很多事情都是要組成事務來執行的。既然它那麼重要,下面我們就來深入的瞭解一下什麼是事務吧。
一.事務的四個特徵ACID
事務的四個特徵非常重要,只有滿足這些特徵,才能保證事務執行後只有一個結果:要麼成功,要麼失敗。
(1)原子性(Atomicity):組成交易處理的語句形成了一個邏輯單元,不能只執行其中的一部分。
(2)一致性(Consistemcy):交易處理前後,資料處於一致狀態,保證資料的無損。
(3)隔離性(Isolation):對資料進行修改的多個事務是彼此隔離的,互不影響。
(4)持久性(Durability):事務完成之後,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留,真實的修改了資料庫。
樣本一
---------建立表CREATE TABLE bank( customerName CHAR(10), --顧客姓名 currentMoney number(10) --當前餘額);---------添加餘額不能小於1的約束ALTER TABLE bank ADD CONSTRAINT CK_currentMoney CHECK(currentMoney >= 1);---------插入測試資料INSERT INTO bank(customerName, currentMoney) VALUES(‘張三‘, 1000);INSERT INTO bank(customerName, currentMoney) VALUES(‘李四‘, 1);commit;select * from bank;---------不使用事務完成轉帳操作(總金額異常) update bank set currentMoney=currentMoney-1000 where customerName=‘張三‘; update bank set currentMoney=currentMoney+1000 where customerName=‘李四‘;commit;---------清空資料,delete bank;select * from bank;---------使用事務完成轉賬操作不會出現總金額異常set serveroutput on;declare li_money number(10):=0;begin update bank set currentMoney=currentMoney+1000 where customerName=‘李四‘; select currentMoney into li_money from bank where customerName=‘李四‘; dbms_output.put_line(‘李四當前的餘額是:‘||li_money); update bank set currentMoney=currentMoney-1000 where customerName=‘張三‘;exception when others then dbms_output.put_line(‘撤銷提交‘); rollback;end;--轉帳之後查看結果,李四的錢被復原回去了select * from bank;
二.復原到儲存點
(1)rollback:復原到最初狀態,可以參考樣本一。
(2)rollback to 保留點:復原到保留點。
樣本二
declare num int;begin savepoint a; --建立儲存點a update bank set currentmoney=currentmoney-100 where customername=‘張三‘; savepoint b; --建立儲存點b update bank set currentmoney=currentmoney+100 where customername=‘李四‘; savepoint c; --建立儲存點c num:=# --從提示框接收一個資料,用於操作復原到哪一點。 insert into bank values(‘王五‘,600); savepoint d; --建立儲存點d if num=1 then rollback to a; --當提示框中輸入1時,復原到儲存點a,即全部復原,相當於rollback; elsif num=2 then rollback to b; --當提示框中輸入2時,復原到儲存點b elsif num=3 then rollback to c; --當提示框中輸入3時,復原到儲存點c else rollback to d; --其他情況下,復原到儲存點d end if;end;
三.事務的隔離等級
從上面的樣本中我們可以看到事務帶給我們的巨大好處,保證了資料的一致性,但是,僅僅有保證用事務執行就可以保證資料前後是一致的嗎?在實際情況下,事務是並發執行的,不可避免的會出現多個事務同一時間對相同資料的操作,這樣就會產生各種並發問題。
並發問題:(1)髒讀:事務T1、T2,T1讀取了T2已經更改但還沒有提交的資料,之後,若T2復原,T1讀到的資料就是臨時無效的髒資料。
(2)不可重複讀取:事務T1、T2,T1讀取了一個欄位,然後T2更新了該欄位,當T1再次讀取該欄位時,值就不同了。
(3)幻讀:事務T1、T2,T1讀取了一個欄位,T2在在該表中又插入了一些欄位,當T1再次讀取時,會多出幾行。
為瞭解決上面這些問題,引入了隔離等級,顯然,隔離等級是指一個事務與其他事務的隔離程度,隔離等級都有哪些呢,下面簡單介紹了一下。
隔離等級 |
描述 |
read uncommitted(讀取未提交資料) |
允許事務讀取未被其他事務提交的變更,髒讀、不可重複讀取和幻讀問題都會出現。 |
read committed(讀取已提交資料) |
只允許事務讀取已被其他事務提交的變更,可以避免髒讀,但不可重複讀取和幻讀問題仍然存在。 |
repeatable committed(可重複讀) |
確保一個事務可以多次從一個欄位中讀取到相同的值,避免了髒讀、不可重複讀取,但幻讀問題仍然存在。 |
serializble(序列化) |
在這個事務執行期間,禁止其他表對該表的插入、刪除、修改操作,所有並發問題都可以避免,但效能低下。 |
Oracle 支援的 2 種交易隔離等級:READ COMMITED, SERIALIZABLE。在 Oracle 預設的交易隔離等級為: READ COMMITED。Oracle同時提供了一個Read only的隔離等級。 雖然隔離等級可以避免並發問題,但是要酌情使用,畢竟隔離等級越高,並發性就越弱,這樣軟體的效能就降低了。
四.總結 (1)事務只有一個執行結果,要麼成功,要麼失敗。 (2)事務的四個特點:原子性、一致性、隔離性和持久性。 (3)事務的執行過程中發生問題時,可以直接復原到最初未執行之前的資料狀態,也可以通過savepoint設定儲存點,復原到特定的儲存點位置。 (4)當多個事務同時訪問相同資料時,可能產生並發問題,為了避免這些問題,引入了隔離等級。但是隔離等級越高,雖然資料一致性越好,但是並發性卻更弱。所以要酌情使用。
淺談Oracle事務【轉載竹瀝半夏】