首頁 >資料庫 >mysql教程 >淺談MySQL的事務隔離

淺談MySQL的事務隔離

青灯夜游
青灯夜游轉載
2020-04-04 09:29:511975瀏覽

本篇文章和大家談談MySQL事務隔離。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

淺談MySQL的事務隔離

交易的介紹

#交易就是一組原子性的sql查詢,或者說是一個獨立的工作單元。簡而言之,事務內的語句要麼全部執行成功,要麼全部執行失敗。

在Mysql中,事務支援是在引擎層實現的,但並不是所有的Mysql引擎都支援事務,例如MyISAM引擎就不支援事務,這也是MyISAM被InnoDB取代的重要原因之一。

提到事務,我們一定會想到ACID:

  • 原子性(Atomicity)

  • 一致性(Consistency)

  • 隔離性(Isolation)

  • # 持久性(Durability)

  1. #隔離等級

當資料庫中有多個交易同時執行時,就可能會出現髒讀、不可重複讀取、幻讀等問題,因為就有了事務隔離級別的概念。

SQL標準正定義了四個隔離等級:

READ UNCOMMITTED (未提交讀取)

交易中的修改,即使尚未提交,對其他事務都是可見的。事務可以讀取未提交的數據,也被稱為髒讀(Dirty Read)。

READ COMMITTED(提交讀取)

一個交易提交後,所做的變更才能被其他交易看到。這個等級也叫不可重複讀,因為在事務中執行2次相同的查詢,可能得到的結果是不一樣的。

REPEATABLE READ(可重複讀取)一個事務執行的過程中,總是和這個事務在啟動時看到的資料是一致的。當然在這個層級下,未提交的資料變更對其他交易也是不可見的。

SERIALIZABLE(可串行化)

對同一行記錄,寫入和讀取都會加鎖,當出現讀寫鎖定衝突時,後存取的交易必須等前一個事務執行完成才能繼續執行,就會導致大量的逾時和鎖爭用的問題。

在實作上,資料庫裡面會建立一個視圖,在存取的時候會以視圖的邏輯為準。 在可重複讀取這個隔離等級下,這個視圖是事務開啟的時候創建的,整個事務期間都會使用這個視圖。 在讀取提交的隔離等級下,這個視圖是在sql語句開始執行的時候建立的。

    在讀取未提交的隔離等級下,直接傳回記錄上的最新值,沒有視圖概念。
  • 在串列化的隔離層級下,直接用加鎖的方式避免並行存取。

  • 配置的方式是將啟動參數
  • transaction-isolation

    設定成想要的隔離等級。

  • 查看目前設定:
mysql> show variables like 'transaction_isolation';
+-----------------------+-----------------+
| Variable_name         | Value           |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

總之,存在即合理,不同的隔離等級適用於不同的場景,具體我們應該根據業務場景來決定。

交易隔離的實作

在Mysql中,實際上每筆記錄的更新同時也會記錄一個回溯操作,記錄上的最新值透過回滾操作,都可以得到前一個狀態的值。

系統會自動判斷,當沒有交易再需要回滾日誌時,就會刪除回溯日誌。

為什麼不建議使用長事務:長事務意味著系統裡面會存在很老的事務視圖,由於這些事務隨時可以訪問資料庫裡面的任何數據,所以這個事務提交之前,資料庫裡可能用到的回滾記錄必須保留著,這就會佔用大量的儲存空間。同時長事務也佔用鎖資源,也可能拖垮整個庫。

#########事務啟動的方式###################明確啟動事務語句,begin或start transaction,提交就是commit,回滾用rollback。 ############set autocommit = 0,這個指令會將執行緒的自動提交關掉,表示如果執行一個select 語句,這個交易就啟動了,並且不會自動提交,直到你主動執行commit或rollback,或斷開連線。 ############個人建議還是透過第一種方式明確啟動事務,避免長事務的發生。 ######在 set autocommit = 1 的情況下,用 begin 明確啟動的事務,如果執行 commit 則提交事務。如果執行 commit work and chain,則是提交事務並自動啟動下一個事務,這樣也省去了再次執行 begin 語句的開銷。 #########查詢長事務:#########下面語句是查詢持續時間超過60s的事務###
mysql> select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60;
Empty set (0.00 sec)
###總結下來,我們在開發過程中,盡量少用長事務,如果無法避免,保證邏輯日誌空間夠大,並且支援動態日誌空間成長。監控Innodb_trx表,發現長事務警報。 ######推薦:《###mysql影片教學###》###

以上是淺談MySQL的事務隔離的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:github.io。如有侵權,請聯絡admin@php.cn刪除