一、事務分類
事務是訪問并更新資料庫中各種資料項的一個程式執行單元,事務會把資料庫從一種一致狀態轉換為另一種一致狀態,這就是事務的目的,也是事務模型區別與檔案系統的重要特性之一,
InnoDB 存盤引擎中的事務(READ REPEATABLE 隔離級別)完全符合 ACID 的特性,ACID 是以下 4 個詞的縮寫:
- 原子性(atomicity):資料庫事務是不可分割的作業單位,事務中的資料庫操作要么都成功,要么都不成功,
- 一致性(consistency):將資料庫從一種狀態轉變為下一種一致的狀態,在事務開始之前和事務結束以后,資料庫的完整性約束沒有被破壞,
- 隔離性(isolation):每個讀寫事務的物件對其他事務的操作物件能相互分離,即該事務提交前對其他事務都不可見,通常這使用鎖來實作,
- 持久性(durability):事務一旦提交,其結果就是永久性的,
從事務理論的角度來說,可以把事務分為以下幾種型別:
- 扁平事務(Flat Transactions)
- 帶有保存點的扁平事務(Flat Transactions with Savepoints)
- 鏈事務(Chained Transactions)
- 嵌套事務(Nested Transactions)
- 分布式事務(Distributed Transactions)
1. 扁平事務(Flat Transactions)
最簡單,使用最頻繁的事務,其間的操作是原子的,要么都執行,要么都回滾,也就是通常意義上我們理解的事務概念,
2. 帶有保存點的扁平事務(Flat Transactions with Savepoints)
允許在事務執行程序中回滾到同一事務中較早的一個狀態,保存點(Savepoint)用來通知系統應該記住事務當前的狀態,以便當之后發生錯誤時,事務能回到保存點當時的狀態,

3. 鏈事務(Chained Transactions)
在提交一個事務時,釋放不需要的資料物件,將必要的處理背景關系隱式地傳給下一個要開始的事務,這意味著下一個事務將看到上一個事務的結果,就好像在一個事務中進行的一樣,

4. 嵌套事務(Nested Transactions)
由一個頂層事務(top-level transaction)控制著各個層次的事務,頂層事務之下嵌套的事務被稱為子事務(subtransaction),其控制每一個區域的變換,Moss 對嵌套事務這樣描述:
1)嵌套事務是由若干事務組成的一顆樹,子樹既可以是嵌套事務,也可以是扁平事務,
2)處在葉節點的事務是扁平事務,但是每個子事務從跟到葉節點的距離可以是不同的,
3)位于根節點的事務稱為頂層事務,其他事務稱為子事務,事務的前驅稱為父事務(parent),事務的下一層稱為兒子事務(child),
4)子事務既可以提交也可以回滾,但是它的提交操作并不會馬上生效,除非其父事務已經提交,
5)樹中的任意一個事務的回滾會引起它的所有子事務一同回滾,故子事務僅保留 A、C、I 特性,不具有 D 的特性,

5. 分布式事務(Distributed Transactions)
分布式事務指的是允許多個獨立的事務資源(transactional resources)參與到一個全域的事務中,全域事務要求在其中的所有參與的事務要么都提交,要么都回滾,
另外,在使用分布式事務時,InnoDB 存盤引擎的事務隔離級別必須設定為 SERIALIZABLE,
二、事務控制陳述句
在 MySQL 命令列的默認設定下,事務都是自動提交(auto commit)的,即執行 SQL 陳述句后就會馬上執行 COMMIT 操作,因此要顯示的控制一個事務,就要用到事務控制陳述句,
- START TRANSACTION | BEGIN :顯式地的開啟一個事務;
- COMMIT | COMMIT WORK:提交事務,并使得已對資料庫做的所有修改成為永久性的;
- ROLLBACK | ROLLBACK WORK:回滾用戶的事務并撤銷正在進行的所有未提交的事務;
- SAVEPOINT [identifier]:創建一個保存點,一個事務中可以有多個 SAVEPOINT;
- ROLLBACK TO [SAVEPOINT]:把事務回滾到標記點,而不回滾在此標記點之前的任何作業;
- SET TRANSACTION:用來設定事務的隔離級別;
COMMIT 和 COMMIT WORK 陳述句基本上是一致的,都是用來提交事務,不同之處在于 COMMIT WORK 用來控制事務結束后的行為是 CHAIN 還是 RELEASE 的,該行為受 completion_type 引數控制,
SHOW VARIABLES LIKE '%completion_type%';
以下這些 SQL 陳述句會產生一個隱式的提交操作,即執行完這些陳述句后,會有一個隱式的 COMMIT 操作,即這些 SQL 陳述句執行完是不能被回滾的,
- DDL 陳述句;
- 管理陳述句:ANALYZE TABLE、CACHE INDEX、CHECK TABLE、LOAD INDEX INTO CACHE、OPTIMIZE TABLE、REPAIR TABLE;
- 隱式修改 MySQL 架構的操作:CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD;
三、事務隔離級別
ISO 和 ANIS SQL 標準制定了四種事務隔離級別的標準,分別為:
- Read Uncommitted 讀未提交
- Read Committed 讀已提交
- Repeatable Read 可重復讀
- Serializable 串行化
有關事務隔離級別的內容在 InnoDB 存盤引擎中的鎖 有講解,可參考,
在 INNODB 存盤引擎中,可以使用以下命令來設定當前會話或全域的事務隔離級別:
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]
據了解,大部分的用戶質疑 Serializable 隔離級別帶來的性能問題,但是根據 Jim Gray 在 《Transaction Processing》一書中指出,兩者的開銷幾乎是一樣的,甚至 Serializable 可能更優!!!因此在 InnoDB 存盤引擎中選擇 Repeatable Read 的事務隔離級別并不會有任何性能的損失,同樣地,即使使用 Read Committed 的隔離級別,用戶也不會得到性能的大幅度提升,
在 SERIALIZABLE 的事務隔離級別下,INNODB 存盤引擎會對每個 SELECT 陳述句后自動加上 LOCK IN SHARE MODE,即為每個讀取操作加一個共享鎖,
四、分布式事務
XA(eXtended Architecture)是指由 X/Open 組織提出的分布式交易處理的規范,XA 是一個分布式事務協議,由Tuxedo 提出,所以分布式事務也稱為 XA 事務,
XA 協議主要定義了事務管理器 TM(Transaction Manager,協調者)和資源管理器 RM(Resource Manager,參與者)之間的介面,其中,資源管理器往往由資料庫實作,如 Oracle、DB2、MySQL,這些商業資料庫都實作了 XA 介面,而事務管理器作為全域的調度者,負責各個本地資源的提交和回滾,
XA 事務是基于兩階段提交(Two-phaseCommit,2PC)協議實作的,可以保證資料的強一致性,許多分布式關系型資料管理系統都采用此協議來完成分布式,階段一為準備階段,即所有的參與者準備執行事務并鎖住需要的資源,當參與者 Ready 時,向 TM 匯報自己已經準備好,階段二為提交階段,當 TM 確認所有參與者都 Ready 后,向所有參與者發送 COMMIT 命令,
XA 事務由一個或多個資源管理器(RM)、一個事務管理器(TM)和一個應用程式(ApplicationProgram)組成,
XA 事務的缺點是性能不好,且無法滿足高并發場景,一個資料庫的事務和多個資料庫間的 XA 事務性能會相差很多,因此,要盡量避免 XA 事務,如可以將資料寫入本地,用高性能的訊息系統分發資料,或使用資料庫復制等技術,只有在其他辦法都無法實作業務需求,且性能不是瓶頸時才使用 XA,
SHOW VARIABLES LIKE 'innodb_support_xa';
五、其它
-
redo log 稱為重做日志,恢復提交事務修改的頁操作,用來保證事務的原子性和持久性;undo log 稱為回滾日志,幫助回滾行記錄到某個特定版本及 MVCC 的功能,用來保證事務的一致性;
-
引數
innodb_flush_log_at_trx_commit用來控制重做日志重繪到磁盤的策略,該引數的默認值為 1,表示事務提交時必須呼叫一次 fsync 操作重繪到磁盤;0 表示事務提交時不進行重做日志重繪到磁盤操作,該操作僅在 master thread 中完成(mysql 宕機,未重繪到磁盤的資料會全部丟失);2 表示事務提交時,僅將重做日志寫入檔案系統的快取中,不進行 fsync 操作(只要作業系統不宕機,資料就不會丟); -
磁盤的 fsync 性能是有限的,為了提高磁盤 fsync 的效率,當前資料庫都提供了 group commit 的功能,即一次 fsync 可以重繪確保多個事務日志被寫入檔案;
-
用戶通常對 undo 有這樣誤解:undo 用于將資料庫物理地恢復到執行陳述句或事務之前的樣子 —— 但事實并非如此,undo 是邏輯日志,因此只是將資料庫邏輯地恢復到原來的樣子;
-
最常見的 MySQL 內部的 XA 事務存在于 binlog 與 InnoDB 存盤引擎之間,對于 binlog 日志和 InnoDB 存盤引擎的 REDO 日志,必須同時寫入,其就是用 XA 事務來保障的;
-
不要在回圈中提交事務,而應該把回圈當成一個事務;
-
長事務[Long-Lived Trascactions] 指的是執行時間較長的事務,對于長事務的問題,有時可以通過轉化為小批量(mini batch)的事務來進行處理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/263299.html
標籤:其他
下一篇:Redis基礎:持久化
