- 高性能MySQL(第4版)
- (美)Silvia Botros等
- 1340字
- 2023-11-24 18:39:32
事務
在理解事務的概念之前,接觸數據庫系統的其他高級特性還言之過早。事務就是一組SQL語句,作為一個工作單元以原子方式進行處理。如果數據庫引擎能夠成功地對數據庫應用整組語句,那么就執行該組語句。如果其中有任何一條語句因為崩潰或其他原因無法執行,那么整組語句都不執行。也就是說,作為事務的一組語句,要么全部執行成功,要么全部執行失敗。
本節的內容并非專屬于MySQL,如果讀者已經熟悉ACID事務的概念,可以直接跳到本章后面的“MySQL中的事務”一節。
銀行應用是解釋事務必要性的經典例子。[5]假設一個銀行的數據庫有兩張表:支票表(checking)和儲蓄表(savings)。現在要從用戶Jane的支票賬戶轉移200美元到她的儲蓄賬戶,那么需要至少三個步驟:
1. 確保支票賬戶的余額高于200美元。
2. 從支票賬戶的余額中減去200美元。
3. 在儲蓄賬戶的余額中增加200美元。
以上三步操作必須打包在一個事務中,以保證一旦其中任何一步失敗,都能夠回滾所有的操作。
可以用START TRANSACTION語句啟動事務,然后要么使用COMMIT提交事務將修改的數據持久保留,要么使用ROLLBACK撤銷所有的修改。本例中的事務的SQL語句可能如下:

單純的事務概念并不是故事的全部。試想一下,如果數據庫在執行第4條語句時崩潰了,會發生什么?天知道,客戶可能會損失200美元。再假如,在執行到第3條語句和第4條語句之間時,另外一個進程要刪除支票賬戶的所有余額會發生什么?結果可能是銀行不知不覺白白給了Jane 200美元。
在這一系列操作中,有更多的失敗可能性。連接可能會斷開、會超時,甚至數據庫服務器在操作執行過程中會崩潰。這就是為什么存在高度復雜且緩慢的兩階段提交系統的典型原因:為了應對各種失敗場景。
除非系統通過嚴格的ACID測試,否則空談事務的概念是不夠的。ACID代表原子性(atomicity)、一致性(consistency)、隔離性(isolation)和持久性(durability)。一個確保數據安全的事務處理系統,必須滿足這些密切相關的標準。
原子性(atomicity)
一個事務必須被視為一個不可分割的工作單元,整個事務中的所有操作要么全部提交成功,要么全部失敗回滾。對于一個事務來說,不可能只執行其中的一部分操作,這就是事務的原子性。
一致性(consistency)
數據庫總是從一個一致性狀態轉換到下一個一致性狀態。在前面的例子中,一致性確保了,即使在執行第3、4條語句之間時系統崩潰,支票賬戶中也不會損失200美元。如果事務最終沒有提交,該事務所做的任何修改都不會被保存到數據庫中。
隔離性(isolation)
通常來說,一個事務所做的修改在最終提交以前,對其他事務是不可見的,這就是隔離性帶來的結果。在前面的例子中,當執行完第3條語句、第4條語句還未開始時,此時有另外一個賬戶匯總程序開始運行,其看到的支票賬戶的余額并沒有被減去200美元。后面我們討論隔離級別(isolation level)的時候,會發現為什么我們要說“通常來說”是不可見的。
持久性(durability)
一旦提交,事務所做的修改就會被永久保存到數據庫中。此時即使系統崩潰,數據也不會丟失。持久性是一個有點模糊的概念,實際上持久性也分很多不同的級別。有些持久性策略能夠提供非常強的安全保障,而有些則未必。而且不可能有100%的持久性保障(如果數據庫本身就能做到真正的持久性,那么備份又怎么能增加持久性呢?)。
ACID事務和InnoDB引擎提供的保證是MySQL中最強大、最成熟的特性之一。雖然它們在吞吐量方面做了一定的權衡,但如果應用得當,就可以避免在應用層實現大量復雜邏輯。