事務是訪問並更新數據庫中各類數據項的一個程序執行單元,事務會把數據庫從一種一致狀態轉換爲另外一種一致狀態,這就是事務的目的,也是事務模型區別與文件系統的重要特性之一。html
InnoDB 存儲引擎中的事務(READ REPEATABLE 隔離級別)徹底符合 ACID 的特性。ACID 是如下 4 個詞的縮寫:mysql
從事務理論的角度來講,能夠把事務分爲如下幾種類型:sql
最簡單,使用最頻繁的事務,其間的操做是原子的,要麼都執行,要麼都回滾,也就是一般意義上咱們理解的事務概念。數據庫
容許在事務執行過程當中回滾到同一事務中較早的一個狀態,保存點(Savepoint)用來通知系統應該記住事務當前的狀態,以便當以後發生錯誤時,事務能回到保存點當時的狀態。
緩存
在提交一個事務時,釋放不須要的數據對象,將必要的處理上下文隱式地傳給下一個要開始的事務,這意味着下一個事務將看到上一個事務的結果,就好像在一個事務中進行的同樣。
架構
由一個頂層事務(top-level transaction)控制着各個層次的事務,頂層事務之下嵌套的事務被稱爲子事務(subtransaction),其控制每個局部的變換。Moss 對嵌套事務這樣描述:
1)嵌套事務是由若干事務組成的一顆樹,子樹既能夠是嵌套事務,也能夠是扁平事務。併發
2)處在葉節點的事務是扁平事務,可是每一個子事務從跟到葉節點的距離能夠是不一樣的。分佈式
3)位於根節點的事務稱爲頂層事務,其餘事務稱爲子事務,事務的前驅稱爲父事務(parent),事務的下一層稱爲兒子事務(child)。ide
4)子事務既能夠提交也能夠回滾,可是它的提交操做並不會立刻生效,除非其父事務已經提交。高併發
5)樹中的任意一個事務的回滾會引發它的全部子事務一同回滾,故子事務僅保留 A、C、I 特性,不具備 D 的特性。
分佈式事務指的是容許多個獨立的事務資源(transactional resources)參與到一個全局的事務中,全局事務要求在其中的全部參與的事務要麼都提交,要麼都回滾。
另外,在使用分佈式事務時,InnoDB 存儲引擎的事務隔離級別必須設置爲 SERIALIZABLE。
在 MySQL 命令行的默認設置下,事務都是自動提交(auto commit)的,即執行 SQL 語句後就會立刻執行 COMMIT 操做。所以要顯示的控制一個事務,就要用到事務控制語句。
COMMIT 和 COMMIT WORK 語句基本上是一致的,都是用來提交事務,不一樣之處在於 COMMIT WORK 用來控制事務結束後的行爲是 CHAIN 仍是 RELEASE 的,該行爲受 completion_type
參數控制。
SHOW VARIABLES LIKE '%completion_type%';
如下這些 SQL 語句會產生一個隱式的提交操做,即執行完這些語句後,會有一個隱式的 COMMIT 操做,即這些 SQL 語句執行完是不能被回滾的。
ISO 和 ANIS SQL 標準制定了四種事務隔離級別的標準,分別爲:
有關事務隔離級別的內容在 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、DB二、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)的事務來進行處理。