數(shù)據(jù)庫高級:事務

事務

1. 為什么要有事務

事務廣泛的運用于訂單系統(tǒng)、銀行系統(tǒng)等多種場景

例如:

A用戶和B用戶是銀行的儲戶,現(xiàn)在A要給B轉賬500元,那么需要做以下幾件事:

  1. 檢查A的賬戶余額>500元;
  2. A 賬戶中扣除500元;
  3. B 賬戶中增加500元;

正常的流程走下來,A賬戶扣了500,B賬戶加了500,皆大歡喜。

那如果A賬戶扣了錢之后,系統(tǒng)出故障了呢?A白白損失了500,而B也沒有收到本該屬于他的500。

以上的案例中,隱藏著一個前提條件:A扣錢和B加錢,要么同時成功,要么同時失敗。事務的需求就在于此

所謂事務,它是一個操作序列,這些操作要么都執(zhí)行,要么都不執(zhí)行,它是一個不可分割的工作單位。

例如,銀行轉賬工作:從一個帳號扣款并使另一個帳號增款,這兩個操作要么都執(zhí)行,要么都不執(zhí)行。所以,應該把他們看成一個事務。事務是數(shù)據(jù)庫維護數(shù)據(jù)一致性的單位,在每個事務結束時,都能保持數(shù)據(jù)一致性

事務四大特性(簡稱ACID)

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔離性(Isolation)
  • 持久性(Durability)

以下內(nèi)容出自《高性能MySQL》第三版,了解事務的ACID及四種隔離級有助于我們更好的理解事務運作。

下面舉一個銀行應用是解釋事務必要性的一個經(jīng)典例子。假如一個銀行的數(shù)據(jù)庫有兩張表:支票表(checking)和儲蓄表(savings)。現(xiàn)在要從用戶Jane的支票賬戶轉移200美元到她的儲蓄賬戶,那么至少需要三個步驟:

  1. 檢查支票賬戶的余額高于或者等于200美元。
  2. 從支票賬戶余額中減去200美元。
  3. 在儲蓄帳戶余額中增加200美元。

上述三個步驟的操作必須打包在一個事務中,任何一個步驟失敗,則必須回滾所有的步驟。

可以用START TRANSACTION語句開始一個事務,然后要么使用COMMIT提交將修改的數(shù)據(jù)持久保存,要么使用ROLLBACK撤銷所有的修改。事務SQL的樣本如下:

  1. start transaction;
  2. select balance from checking where customer_id = 10233276;
  3. update checking set balance = balance - 200.00 where customer_id = 10233276;
  4. update savings set balance = balance + 200.00 where customer_id = 10233276;
  5. commit;

一個很好的事務處理系統(tǒng),必須具備這些標準特性:

  • 原子性(atomicity)

一個事務必須被視為一個不可分割的最小工作單元,整個事務中的所有操作要么全部提交成功,要么全部失敗回滾,對于一個事務來說,不可能只執(zhí)行其中的一部分操作,這就是事務的原子性

  • 一致性(consistency)

數(shù)據(jù)庫總是從一個一致性的狀態(tài)轉換到另一個一致性的狀態(tài)。(在前面的例子中,一致性確保了,即使在執(zhí)行第三、四條語句之間時系統(tǒng)崩潰,支票賬戶中也不會損失200美元,因為事務最終沒有提交,所以事務中所做的修改也不會保存到數(shù)據(jù)庫中。)

  • 隔離性(isolation)

通常來說,一個事務所做的修改在最終提交以前,對其他事務是不可見的。(在前面的例子中,當執(zhí)行完第三條語句、第四條語句還未開始時,此時有另外的一個賬戶匯總程序開始運行,則其看到支票帳戶的余額并沒有被減去200美元。)

  • 持久性(durability)

一旦事務提交,則其所做的修改會永久保存到數(shù)據(jù)庫。(此時即使系統(tǒng)崩潰,修改的數(shù)據(jù)也不會丟失。)

事務命令

表的引擎類型必須是innodb類型才可以使用事務,這是mysql表的默認引擎

查看表的創(chuàng)建語句,可以看到engine=innodb

-- 選擇數(shù)據(jù)庫
use jing_dong;
-- 查看goods表
show create table goods;

開啟事務,命令如下:

  • 開啟事務后執(zhí)行修改命令,變更會維護到本地緩存中,而不維護到物理表中
begin;
或者
start transaction;

提交事務,命令如下

  • 將緩存中的數(shù)據(jù)變更維護到物理表中
commit;

回滾事務,命令如下:

  • 放棄緩存中變更的數(shù)據(jù)
rollback;

注意

  1. 修改數(shù)據(jù)的命令會自動的觸發(fā)事務,包括insert、update、delete
  2. 而在SQL語句中有手動開啟事務的原因是:可以進行多次數(shù)據(jù)的修改,如果成功一起成功,否則一起會滾到之前的數(shù)據(jù)
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。