MySql事務概述


事務是訪問並更新數據庫中各種數據項的一個程序執行單元。在事務中的操作,要么都執行修改,要么都不執行,這就是事務的目的,也是事務模型區別於文件系統的重要特征之一。

嚴格上來說,事務必須同時滿足4個特性,即通常所說事務的ACID特性。雖然理論上定義了嚴格的事務要求,但是數據庫廠商出於各種目的並沒有嚴格滿足事務的ACID標准。例如,對於MYSQL的NDB Cluster引擎,雖然支持事務,但是不滿足D的要求,即持久性的要求。對於Oracle數據庫來說,其默認的事務隔離級別為READ COMMITTED,不滿足I的要求,即隔離性的要求。對於InnoDB存儲引擎而言,默認的事務隔離級別是READ REPRATABLE,完全遵循和滿足事務的ACID特性。

A(atomicity),原子性。原子性指整個數據庫事務是不可分割的工作單位。只有使事務中所有的數據庫操作都執行成功,整個事務的執行才算成功。事務中任何一個SQL語句執行失敗,那么已經執行成功的SQL語句也必須撤銷,數據庫狀態應該退回到事務前的狀態。

C(consistency),一致性。一致性是指事務將數據庫從一種狀態轉變為另一種狀態。在事務的開始之前和事務結束以后,數據庫的完整性約束沒有被破壞。

I(isolation),隔離性。隔離性還有其他的稱呼,如並發控制、可串行化、鎖。事務的隔離性要求每個讀寫事務的對象與其他事務的操作對象能互相分離,即該事務提交前對其他事務都不可見,這通常使用鎖來實現。數據庫系統中提供了一種粒度鎖的策略,允許事務僅鎖住一個實體對象的子集,以此來提高事務之間的並發度。(如果是全表鎖,事務之間基本就無法實現並發,但是如果只鎖住表中處理的行,可以提高事務的並發度)

D(durability),持久性。事務一旦提交,其結果就是永久性的。即使發生宕機等故障,數據庫也能將數據恢復。需要注意的是,持久性只能從事務本身的角度來保證結果的永久性,如事務提交后,所有的變化都是永久的,即使當數據庫由於崩潰而需要恢復時,也能保證恢復后提交的數據都不會丟失。

事務的(ACID)特性是由關系數據庫管理系統(RDBMS,數據庫系統)來實現的。數據庫管理系統采用日志來保證事務的原子性、一致性和持久性。日志記錄了事務對數據庫所做的更新,如果某個事務在執行過程中發生錯誤,就可以根據日志,撤銷事務對數據庫已做的更新,使數據庫退回到執行事務前的初始狀態。數據庫管理系統采用鎖機制來實現事務的隔離性。當多個事務同時更新數據庫中相同的數據時,只允許持有鎖的事務能更新該數據,其他事務必須等待,直到前一個事務釋放了鎖,其他事務才有機會更新該數據。

事務分類

  • 扁平事務,最簡單,使用最頻繁的事務。在扁平事務中,所有的操作都處於一個層次,其有BEGIN WORK開始,有COMMIT WORK或ROLLBACK WORK結束。處於之間的操作是原子的,要么全部執行,要么全部回滾。
  • 帶有保存點的扁平事務,除了扁平事務支持的操作外,允許在事務執行過程中回滾到同一事務中較早的一個狀態,這是因為可能有些事務在執行過程中出現的錯誤並不會對有的操作都無效,放棄整個事務不合乎要求,開銷也太大。保存點用來通知系統應該記住事務當前的狀態,以便以后發生錯誤時,事務能回到該狀態。
  • 鏈事務可視為保存點模式的一個變種。
  • 嵌套事務是一個層次結構框架。
  • 分布式事務

事務控制語句

在MYSQL命令行的默認設置下,事務都是自動提交的,即執行SQL語句后就會馬上執行COMMIT操作。因此要顯示的開啟一個事務必須使用命令BEGIN和START TRANSACTION,或者執行命令SET AUTOCOMMIT = 0,以禁用當前會話的自動提交。事務控制語句如下:

  • START TRANSACTION | BEGIN:顯示的開啟一個事務。在存儲過程中,MYSQL數據庫的分析器會自動將BEGIN識別為BEGIN...END,因此在存儲過程中只能使用START TRANSACTION語句來開啟一個事務。
  • COMMIT:要想使用這個語句的最簡形式,只需發出COMMIT。COMMIT會提交事務,並使已對數據庫進行的所有修改成為永久性的。COMMIT和COMMIT WORK語句基本上是一致的,都是用來提交事務。不同的是COMMIT WORK用來控制事務結束后的行為是CHAIN還是RELEASE的。如果是CHAIN方式,那么事務就變成了鏈事務。用戶可以通過參數completion_type來進行控制,默認該參數是0,表示沒有任何操作。在這種設置下,COMMIT和COMMIT WORK是完全等價的。當參數值為1時,COMMIT WORK等價於COMMIT AND CHAIN,表示馬上自動開啟一個相同隔離級別的事務。當參數值為1時,COMMIT WORK等價於COMMIT AND RELEASE。當提交事務后會自動斷開與服務器連接。
  • ROLLBACK:回滾會結束用戶的事務,並撤銷正在進行的所有未提交的修改。
  • SAVEPOINT identifiter:SAVEPOINT允許用戶在事務中創建一個保存點,一個事務可以有很多個保存點。
  • RELEASE SAVEPOINT identifier:刪除一個事務的保存點,當沒有一個保存點執行這語句時,會拋出一個異常。
  • ROLLBACK to [SAVEPOINT] identifier:這個語句與SAVEPOINT命令一起使用。可以把事務回滾到標記點,而不回滾到此標記點之前的任何工作。注意:雖然有ROLLBACK,但是它並沒有真正的結束一個事務,因此即使執行了ROLLBACK TO SAVEPOINT,之后也需要顯示的運行COMMIT或ROLLBACK命令。
  • SET TRANSACTION:這個語句用來設置事務的隔離級別。InnoDB存儲引擎提供的事務隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。

事務的隔離級別

ANSI SQL標准定義的四個隔離級別為:

  1. READ UNCOMMITTED(未提交讀),事務中的修改,即使沒有提交,在其他事務也都是可見的。事務可以讀取未提交的數據,這也被稱為臟讀。
  2. READ COMMITTED(提交讀),一個事務從開始直到提交之前,所做的任何修改對其他事務都是不可見的。這個級別有時候也叫做不可重復讀,因為兩次執行相同的查詢,可能會得到不一樣的結果。因為在這2次讀之間可能有其他事務更改這個數據,每次讀到的數據都是已經提交的。
  3. REPEATABLE READ(可重復讀),解決了臟讀,也保證了在同一個事務中多次讀取同樣記錄的結果是一致的。但是理論上,可重讀讀隔離級別還是無法解決另外一個幻讀的問題,指的是當某個事務在讀取某個范圍內的記錄時,另外一個事務也在該范圍內插入了新的記錄,當之前的事務再次讀取該范圍內的記錄時,會產生幻行。
  4. SERIALIZABLE(可串行化),它通過強制事務串行執行,避免了前面說的幻讀的問題。

1、臟讀(dirty read):一個事務可以讀取另一個尚未提交事務的修改數據。

2、不可重復讀(nonrepeatable read):在同一個事務中,同一個查詢在T1時間讀取某一行,在T2時間重新讀取這一行時候,這一行的數據已經發生修改,可能被更新了(update),也可能被刪除了(delete)。

3、幻像讀(phantom read):在同一事務中,同一查詢多次進行時候,由於其他插入操作(insert)的事務提交,導致每次返回不同的結果集。

InnoDB采用MVCC來支持高並發,並實現了四個標准的隔離級別。其默認級別是REPEATABLE READ(可重復讀),並且通過間隙鎖(next-key locking)策略防止幻讀的出現。間隙鎖使得InnoDB不僅僅鎖定查詢涉及的行,還會對索引中的間隙進行鎖定,以防止幻影的插入。

隔離級別越低,事務請求的鎖越少或保持鎖的時間就越短。所以很多數據庫系統默認的事務隔離級別是READ COMMITTED。質疑SERIALIZABLE隔離級別的性能,但是InnoDB存儲引擎認為兩者的開銷是一樣的,所以默認隔離級別使用REPEATABLE READ。

用命令設置當前會話或全局會話的事務隔離級別。

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL 
{
    READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE
}

如果想啟動時就設置事務的默認隔離級別,修改MYSQL的配置文件,在[mysqld]中添加如下行:

[mysqld]
transaction-isolation = READ-COMMITTED

分布式事務編程

InnoDB存儲引擎提供了對於XA事務的支持,並通過XA事務來支持分布式事務的實現。分布式事務指的是允許多個獨立的事務資源參與到一個全局的事務中。事務資源通常是關系型數據庫系統,也可以是其他類型的資源。全局事務要求在其中的所有參與的事務要么都提交,要么都回滾,這對於事務的ACID要求又有了提高。在使用分布式事務時,InnoDB存儲引擎的事務隔離級別必須設置成SERIALIZALE。

XA事務由一個或多個資源管理器、一個事務管理器、以及一個應用程序組成。

  • 資源管理器:提供訪問事務資源的方法。通常一個數據庫就是一個資源管理器。
  • 事務管理器:協調參與全局事務中的各個事務。需要和參與到全局事務中的所有資源管理器進行通信。
  • 應用程序:定義事務的邊界,指定全局事務中的操作。

在MYSQL數據庫的分布式事務中,資源管理器就是MYSQL數據庫,事務管理器為連接到MYSQL服務器的客戶端。

分布式事務使用兩段式提交(two-phase commit)的方式。在第一階段,所有參與全局事務的節點都會開始准備(PREPARE),告訴事務管理器他們准備好了。第二階段,事務管理器告訴資源管理器執行ROLLBACK或COMMIT。如果任何一個節點顯示不能提交,則所有的節點都會被告知需要回滾。與本地事務不同的是,需要多一次的PREPARE操作,待收到所有節點的同意信息后,再進行COMMIT或ROLLBACK操作。

轉載請注明出處。
作者:wuxiwei
出處:http://www.cnblogs.com/wxw16/p/6128582.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM