本文主要包含內容:
(1) 事務的概念與ACID
(2)事務的隔離等級
(3)MySQL中的事務
理解事務是其它高階概念的基礎。
事務:事務就是一組原子性的SQL查詢,或則說是獨立的執行單元,要麼全部成功,要麼全部失敗,如果失敗了就回滾到事務之前的狀態。
如下來理解資料庫中關於ACID的概念:原子性、一致性、隔離性、持久性。
(1)原子性:事務中的操作是一個不可分割的整體單元,要麼全部都做,要麼全部不做。
(2)一致性:交易執行前後資料庫都必須處於一致性狀態。
(3)隔離性:通常來說,一個事物所做的修改在最終提交之前對其餘交易是不可見的。這裡就涉及到事務的隔離等級的問題了。
(4)持久性:一旦交易提交完成,修改就是永久的,即使伺服器宕機也不會影響到。
為了更好地理解ACID,以下以銀行帳戶轉帳為例進行說明:
-- 开始事务START TRANSACTION; -- 查询支票账户余额+ SELECT balance FROM checking WHERE customer_id = 10233276;+ -- 将支票账户减去200UPDATE checking SET balance = balance - 200.00 WHERE customer_id = 10233276; -- 将余额账户增加200UPDATE savings SET balance = balance + 200.00 WHERE customer_id = 10233276; -- 提交事务更新COMMIT;
原子性:要麼完全提交(10233276的checking餘額減少200,savings 的餘額增加200) ,要嘛完全回滾(兩個表的餘額都不改變)
一致性:這個例子的一致性體現在200元不會因為資料庫系統運行到第3行之後,第4行之前時崩潰而不翼而飛,因為事物還沒有提交。
隔離性:允許在一個事務中的操作語句會與其他事務的語句隔離開,例如事務A運行到第3行之後,第4行之前,此時事務B去查詢checking餘額時,它仍然能夠看到在事務A中被減去的200元(帳戶錢不變),因為事務A和B是彼此隔離的。在事務A提交之前,事務B觀察不到資料的改變。
持久性:這個很好理解,就是交易提交之後修改就是永久的。
事務跟鎖一樣都會需要大量工作,因此你可以根據你自己的需求來決定是否需要事務支持,從而選擇不同的儲存引擎。
SQL定義了四種隔離級別,用來限定交易內哪些資料是可見的。很明顯低階的隔離等級擁有較高的並發性,系統開銷也更加小,但是隨之而來的就是帶來的資料安全性問題。
Read Uncommitted(未提交讀取)
在該隔離級別,所有交易都可以看到其他未提交交易的執行結果。讀取未提交的數據,也稱為髒讀(Dirty Read)。該等級用的很少。
Read Committed(提交讀取)
這是大多數資料庫系統的預設隔離等級(但不是MySQL預設的)。它滿足了隔離的簡單定義:一個交易只能看見已經提交事務所所做的改變,換句話說就是交易提交之前對其餘事務不可見。這種隔離等級也支援不可重複讀取(Nonrepeatable Read),因為相同交易的其他實例在該實例處理其間可能會有新的commit,所以相同select查詢可能會傳回不同結果。
Repeatable Read(可重複讀取)
#這是MySQL的預設交易隔離級別,它確保相同交易的多個實例在並發讀取資料時,會看到同樣的資料行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當使用者讀取某一範圍的資料行時,另一個事務又在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的“幻影” 行。 InnoDB和Falcon儲存引擎透過多版本並發控制(MVCC,Multiversion Concurrency Control)機制解決了這個問題。
Serializable(可串行化)
這是最高的隔離級別,它強制事務都是串行執行的,使之不可能相互衝突,從而解決幻讀問題。換言之,它是在每個讀取的資料行上加上共享鎖定。在這個級別,可能導致大量的超時現象和鎖定競爭。在
MySQL中實作這四個隔離界別可能產生的問題如下:
#MySQL中預設的是採取自動提交模式(AutoCommit),也就是說只要不是顯示的開啟一個事務,每個查詢操作都被當作一個事務執行提交的操作。
我們可以透過設定 AUTOCOMMIT 變數來啟動或則停用自動提交模式。
設定1表示啟用AUTOCOMMIT,0表示停用AUTOCOMMIT。
#本文主要包含一下內容:
(1) 事務的概念與ACID
(2)事務的隔離等級
(3)MySQL中的事務
以上是高效能MySQL-詳解交易與隔離級別的詳細內容。更多資訊請關注PHP中文網其他相關文章!