日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在使用數據庫的過程中,事務通常是我們一個很熟悉的概念。

事務的主要目標是確保一組數據庫操作全部成功或全部失敗。

在MySQL中,事務支持是在存儲引擎級別實現的。

需要注意的是,MySQL 是一個支持多種存儲引擎的系統,但并非所有引擎都提供事務支持。例如,MySQL原生的MyISAM存儲引擎不支持事務,這也是InnoDB取代MyISAM的重要原因之一。

在這篇文章中,將以InnoDB為例,深入研究MySQL對事務支持的具體實現,并根據這些原則提供實用的建議。希望這些案例研究能夠加深您對MySQL事務原理的理解。

隔離性

當提到事務時,ACID(原子性、一致性、隔離性、持久性)肯定是我們首先想到的一個術語。今天,我們將深入研究其中一個方面,即ACID的Isolation隔離性。

當多個事務在數據庫上同時運行時,可能會導致諸如臟讀,不可重復讀和幻讀之類的問題。

為了解決這些問題,引入了隔離級別的概念。

我們要清楚的是,隔離級別越高,執行效率就越低。因此,很多時候我們需要在兩者之間取得平衡。

SQL標準定義了四種事務隔離級別:

  • 讀未提交:事務提交之前,它所做的更改對于其他事務是可見的。
  • 已提交讀:提交事務后,它所做的更改對其他事務可見。
  • 可重復讀:事務執行期間看到的數據與事務啟動時最初看到的數據保持一致。在Repeatable Read隔離級別中,未提交的更改對于其他事務也是不可見的。
  • Serialized:顧名思義,對于同一行記錄,“寫”操作會加一個“寫鎖”,“讀”操作會加一個“讀鎖”。如果讀鎖和寫鎖之間發生沖突,稍后嘗試訪問的事務必須等待前一個事務完成才能繼續。

已提交讀和可重復讀的隔離級別確實有點難以掌握。

示例

為了幫助說明這些隔離級別,讓我們考慮一個示例。假設我們有一個數據表 T,只有一列和一行包含值1。


mysql > create table test_table(id int ) engine = InnoDB; 

mysql > insert test_table(id) values ( 1 ) ;

以下是按時間順序執行的兩個事務的行為:

深入理解MySQL 事務

 

現在我們看看在不同隔離級別下會產生的不同結果,以及場景中V1、V2和 V3的值是什么。

  • 未提交讀: V1的值是2。在這種情況下,即使事務 2 尚未提交,事務1也能看到事務2更新后的結果。因此,V2 和 V3 也都是 2。
  • 已提交讀:V1是1,V2是2事務 2 的更新僅在提交后對事務 1 可見。因此,V3的值也是2。
  • 可重復讀:V1和V2都是1,但V3是2。V2是1的原因是為了滿足事務執行過程中看到的數據必須從頭到尾保持一致的要求
  • 串行化:當事務 2 嘗試將值更新為 2 時,它將被鎖定。它只能在事務 1 提交后才能繼續。因此,從事務1的角度來看,V1和V2的值為1,而V3的值為2。

在實現上,數據庫創建一個視圖,訪問是基于這個視圖的邏輯結果。

可重復讀隔離級別中,該視圖在事務開始時創建,并在整個事務中使用。

讀已提交隔離級別中,此視圖是在每個 SQL 語句執行開始時創建的。

值得注意的是,讀未提交隔離級別直接返回記錄上的最新值,沒有視圖的概念,而序列化隔離級別則采用鎖定來直接防止并發訪問。

很明顯,不同隔離級別下的數據庫行為有所不同。事實上,Oracle 的默認隔離級別是已提交讀。因此,對于從Oracle 遷移到MySQL 的應用程序來說,MySQL為了保持數據庫隔離級別的一致性,必須記住將 MySQL 的隔離級別設置為“已提交讀”。

事務隔離的實現
現在我們了解了事務隔離級別,讓我們仔細看看事務隔離是如何實現的。

我們先深入研究可重復讀隔離級別的細節。

在MySQL中,實際上,每條記錄在更新時都伴隨有一條回滾記錄。可以通過使用此回滾記錄訪問先前的狀態來獲取記錄上的最新值。

假設某個值依次從1過渡到2、3、4。在回滾日志中,您會發現類似以下的記錄:

深入理解MySQL 事務

 

當前值為4,但是查詢這條記錄時,不同時間開始的事務會有不同的read-views。

如圖所示,在read-views 1、2 和 3中,該記錄的值分別為1、2和4。同一條記錄在系統中可以有多個版本,這稱為多版本并發控制(MVCC)。

Read-View 1如果想獲取 value 1,必須按順序執行 圖中所示的所有回滾操作。

此外,即使當前有另一個事務更改4為5,該事務也不會與與讀取視圖 1、2 和 3 關聯的事務發生沖突。

您可能想知道回滾日志何時被刪除,因為它們不能無限期地保留。答案是當不再需要它們時將其刪除。

換句話說,當沒有事務需要訪問回滾日志時,系統將確定可以刪除它們。

什么時候不再需要它們?當系統中沒有早于回滾日志的讀取視圖時會將他們刪除。

基于上面提供的解釋,我們來討論一下為什么建議盡可能避免長時間運行的事務。

長時間運行的事務會導致系統中出現非常多舊的事務視圖。由于這些事務可以隨時訪問數據庫中的任何數據,因此它們可能需要的所有回滾記錄都必須保留在數據庫中,直到事務提交為止。這反過來又導致大量的存儲空間消耗。

在 MySQL 5.5 之前的版本中,回滾日志與數據字典一起存儲在 ibdata 文件中。即使長時間運行的事務最終提交并且回滾段被清除,文件大小也不會減少。

長時間運行的事務還會占用鎖資源,并有可能影響整個數據庫的性能。

開啟事務的方式

如前所述,長時間運行的交易存在潛在風險,因此強烈建議盡可能避免它們。

在許多情況下,開發人員并沒有故意使用長時間運行的事務;通常,這是由于誤用造成的。

MySQL提供了幾種發起事務的方式:

  • BEGIN使用語句或顯式啟動事務START TRANSACTION。提交和回滾對應的語句是COMMIT和ROLLBACK。
  • using SET AUTOCOMMIT=0是一個禁用當前線程自動提交的命令。這意味著如果您只執行一條 SELECT 語句,則會啟動一個事務,并且不會自動提交。此事務將持續存在,直到您主動執行COMMITorROLLBACK語句或與數據庫斷開連接。

SET AUTOCOMMIT=0某些客戶端連接框架可能會在連接成功后默認執行命令。
這會導致后續查詢位于事務內,如果連接長時間保持打開狀態,則可能會導致意外的長時間運行事務。

因此,建議通過語句SET AUTOCOMMIT=1顯式使用和啟動事務。

分享到:
標簽:MySQL
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定