您的位置:首页 > 其它

Transaction and ACID

2016-03-19 17:55 232 查看


Database Transaction第一話: ACID


什麼是Database Transaction

一個transaction,就是一組一連串對資料庫進行Read和Write的動作

只有Read和Write這2種

Read
Write

因為我也想不到其他種動作了

Delete也算在Write裡面喔

wiki上寫說:

A transaction comprises a unit of work performed within a database management system (or similar system) against database.

老實說

我查了很久「a unit of work」在中文是什麼意思

他的意思應該是

Transaction包含1個單元,

什麼樣的1個單元

1個工作的單元

看到這裡不太懂沒關係

我也是猜測的

了解Transaction真正的意思就好

一個transaction,就是一組一連串對資料庫進行Read和Write的動作

一個transaction長這樣

我用pseudo code表示

因為一個transaction只有2種結局

全部SQL執行成功 -> commit;

只要有一個SQL失敗 -> rollback;

所以我最後面有個判斷式

看完pseudo code會解釋transaction的2種結局

Begin Transaction

read();
write();

read();
write();

if (success) {
commit;
} else {
rollback;
}


實際運用上

如果是在資料庫中

一個transaction就是commit和commit中間

全部的SQL

就是一個transaction

commit;
insert into member (
account, englishName, chineseName) values (
'karenten10', 'karen', '吳佳儒');

update member
set englishName = 'Karen Wu'
where account = 'karenten10';

commit;


以上面這個例子來說

這個transaction包含2個動作

一個insert

一個update

如果在程式碼中

以java來說

也是commit和commit中間

全部的SQL

...前面程式省很大
conn.commit();
stmt.execute("insert into member ( "
+ " account, englishName, chineseName) values ("
+ " 'karenten10', 'karen', '吳佳儒'");

stmt.execute("update member "
+ " set englishName = 'Karen Wu'"
+ " where account = 'karenten10'");
conn.commit();


以上面這個例子來說

這個transaction包含2個動作

一個insert

一個update


transaction的2種結局

commit

一個transaction要嘛就是

裡面SQL全部執行成功

然後將執行結果提交給資料庫 --> 也就是commit

rollback

不然只要裡面SQL只要有一個失敗

就要把前面做過的事情全部還原

當作什麼都沒發生過 --> 這就是rollback

寫到這裡佳儒不禁捫心自問

為什麼transaction要這樣設計啊

一定有它的道理

因為就算沒有全部SQL執行成功

至少他也執行到某個程度了啊

為什麼不要把這部分的成果提交出去呢

佳儒想到了一個現實生活案例:

假如佳儒今天到商店去買東西

選好東西後

到櫃檯作結賬

這時候過程的pseudo code如下

Begin Transaction

收銀員刷條碼,告知佳儒價格為$728元;
佳儒從錢包掏出錢,交給收銀員;
收銀員確認錢足夠,開始打發票,找零錢給佳儒;
佳儒把東西帶回家;

if (success) {
commit;
} else {
rollback;
}


假如佳儒在付賬時

發現錢帶不夠

例如我已拿出$500給收銀員時

才發現錢包只剩下$10呢

這時現實生活中會怎麼做

當然是收銀員會把$500退還給我

然後把商品收回去,重新放回架上

一切當作沒發生過一樣

這樣才合理嘛

所以database transaction也是這樣設計的

另外如果只有1個使用者在存取資料庫資料

我們可以不必考慮其他使用者

是否同時在修改相同一筆資料

多個使用者存取資料庫時

如果交易不能併行

那也不用考慮其他使用者

是否同時在修改同一筆資料

就像是收銀員一次只為一位顧客服務

然而在可以多使用者&多交易

可同時進行的資料庫系統中

可能有多位使用者

同時修改同一筆資料

因此如何維持資料的正確性和一致性

就是資料庫系統最大的課題

這時候資料庫系統比較像是麵攤的老闆

他會同時煮好幾位顧客的麵

但是都可以正確上菜

以上案例

也是說明為什麼

transaction必須符合這4個特性


交易的4個特性 - ACID

先來看一下這張圖



要維持Atomicity和Durability要靠Failure Recovery機制
要確保Isolation和Concurrency要靠Concurrency Control機制

這2個機制合起來便是資料庫的「異動管理」

這2個機制稍後在之後的文章再說明

先來說transaction的4個特性


1. Atomicity (原子性)

交易是不可分割的單元,就像原子一樣
它不是全部執行,就是全部不執行
全部執行 => commit,將結果永久儲存於資料庫中
全部不執行 => 如果有一個SQL失敗,rollback,則將之前執行結果的全部回復,當作沒發生過一樣
rollback可能會由以下3種狀況觸發

transaction自己發出的rollback

(1) 可能是提款金額大於存款金額

(2) 使用者輸入密碼錯誤

(3) 提款時按「取消」

資料庫系統本身所發出的rollback

(1) 資料庫系統本身因為負載太大,而不得不先行rollback,待負載減輕時,再予以恢復

(2) 資料庫系統本身發生了Deadlock,而不得不先行rollback

資料庫系統中途發生當機或無法抗拒的意外,這時候沒有人可以發出rollback的命令

(1) 當資料庫系統再度被啟用時,資料庫系統可以利用Transaction Log,判斷哪些Transaction要rollback,哪些Transaction要重新執行


2. Consistency (一致性)

指的是資料在交易前後必須保持一致,直接舉個例子來說明

例如:

A戶頭有300元

B戶頭有500元

A要轉賬100元給B

這時候會有以下動作

A戶頭扣100元,A變成200元
B戶頭加100元,B變成600元

要嘛這2個動作都成功,要嘛這2個動作都不要做

不可以有A戶頭已經扣掉100元

但B戶頭沒加上100元的狀況

不論transaction前後

2個戶頭加總起來是800元

這就是transaction的consistency


3. Isolation (隔離性)

隔離性就是一個transaction在進行時

它所用到的資料庫資料

或是產生的中間結果

不能讓其他transaction影響(寫入)或使用

直到該transaction結束為止(commit)

舉例來說:

如果有個遊戲設計成

會員如果買寶物,會扣10點的點數

會員如果玩遊戲,會扣1點的點數

如果會員同時開了2個視窗

1個視窗買寶物 -> transaction買寶物

1個視窗玩遊戲 -> transaction玩遊戲

Begin Transaction買寶物

取得剩餘點數
檢查是否夠買寶物
如果足夠,點數扣10點
會員寶物清單新增1個寶物

commit;


Begin Transaction玩遊戲

取得剩餘點數
檢查是否夠玩遊戲
如果足夠,點數扣1點
遊戲開始

commit;


那麼如果沒有把「會員點數」table中

那一筆會員的資料鎖定

一次只允許一個transaction進行

如果點數只剩下10點

那有可能會發生會員買了寶物

也玩了一次遊戲

因為系統以為有足夠的點數

佳儒所知道

實際上做到資料鎖定的方式是:

要自己下一個SQL來達成這樣的目的

會員額度的Table叫做memberAccount

(以oracle來說)

select *
from memberAccount
where account = 'karenten10'
for update


這樣karenten10的會員資料

就被鎖定住了

直到目前這個transaction commit後

另1個transaction才能開始使用該筆資料

其實隔離的層級有4種

待佳儒之後的文章再繼續介紹


4. Durability (持續性)

如果在commit的時候

系統發生錯誤

那麼在系統回復後

要繼續完成未完成的工作

這就是transaction的durability

還有許多主題沒有講

就待下幾篇文章繼續

本篇文章寫的出來

主要參考以下來源

感謝他們~

「資料庫系統之理論與實務」,華泰出版社, 曾守正 周韻寰編著
http://en.wikipedia.org/wiki/Database_transaction
http://openhome.cc/Gossip/EJB3Gossip/TransactionABC.html
http://openhome.cc/Gossip/HibernateGossip/IsolationLevel.html
http://structedtext.appspot.com/db/transaction.html
http://openhome.cc/Gossip/JavaGossip-V2/StatementResultSet.htm
http://sjchen.im.nuu.edu.tw/Database/98/Ch07_T.pdf
http://cilab.csie.ncu.edu.tw/students/xiang/course_972/ES750/ES750-14.ppt
http://courses.ywdeng.idv.tw/cust/2011/db/PPT/ch11.ppt
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: