mysql Spring資料庫隔離級別與效能分析

2022-09-29 05:42:08 字數 2581 閱讀 3589

這裡以mysql為例,先明確以下幾個問題:

一.一般專案如果不自己配置事務的話,一般預設的是autocommit,即執行完乙個操作後自動commit,提交事務。

(注:事務是繫結在資料庫操作上的,也就是當程式執行(statement.excute等操作)轉而到資料庫層面上的時候,事務才開始發生)

當然spring可以將幾個資料庫操作動作綁在乙個事務中,這樣就需要介紹下spring事務配置方法,下面介紹的是常用方法,其他方法網上有很多。

spring提供了很多事務配置的策略,很方便,簡要介紹一下:

複製** **如下:

propagation_required

程式設計客棧propagation_required

propagation_required

propagation_required,readonly

propagation_required,readonly

gljpcaops>

一般spring配置事務都是以上的配法,具體引數的意思有不懂的上網自己查吧,那麼需要注意以下幾點:(題外話)

1.我習慣將事務配置在service上,這時需要注意,只有service中以s**e、update等開頭的方法,配置的事務才有效果。如果service中的方法名不是以s**e等開頭的,比如tasks**e()方法,即使在實現類中呼叫了service中的update方法,配置事務也失效,我試過。

2.readonly這個屬性很有意思,因為用了它後,會自動將資料庫的隔離級別提高了一級,由提交讀變為重複讀,這塊我後面說明。

二.資料庫隔離級別

資料庫隔離級別主要有以下四個:不可提交讀,提交讀,重複讀和序列化讀(以下理解可以不看)。

1. isolation_read_uncommitted: 這是事務最低的隔離級別,它充許令外乙個事務可以看到這個事務未提交的資料。

這種隔離級別會產生髒讀,不可重複讀和幻像讀。

2. isolation_read_committed: 保證乙個事務修改的資料提交後才能被另外乙個事務讀取。另外乙個事務不能讀取該事務未提交的資料

3. isolation_repeatable_read: 這種事務隔離級別可以防止髒讀,不可重複讀。但是可能出現幻像讀。

它除了保證乙個事務不能讀取另乙個事務未提交的資料外,還保證了避免下面的情況產生(不可重複讀)。

4. isolation_serializable 這是花費最高代價但是最可靠的事務隔離級別。事務被處理為順序執行。

除了防止髒讀,不可重複讀外,還避免了幻像讀。

mysql預設的隔離級別是重複讀,即 isolation_repeatable_read。

注意:其中未提交讀與序列化讀不常用,未提交讀危險性太高,會讀到很多髒資料。而可序列化讀是通過將讀取的每一行資料加鎖,以耗費效能為代價換取的,所以使用也很少,大部分資料庫的隔離級別是提交讀,比如oracle、sqlserver。而mysql預設的資料隔離級別是可重複讀。

下面我來結合專案分析以下調整資料庫隔離級別對效能的影響:

本地mysql資料庫由isolation_repeatable_read級別降低到isolation_read_committed級別:

場景:未用spring,使用者a在乙個事務中對資料庫發出兩次查詢請求,在兩次查詢之間,使用者b對資料庫的記錄進行修改。

結果:isolation_repeatable_read級別:使用者a兩次查詢結果不一樣。

isolation_read_committed級別:使用者a兩次查詢結果一樣,因為對記錄進行了加鎖操作。

以task模組為例,在本地執行任務首頁,通過對比分析兩種事務處理方式得到如下結果(每次統計資料前均清理瀏覽器快取,統計3次取平均值):

發現降低資料庫事務的隔離級別,對於一些特殊邏輯的操作上,效能有所提公升。

但是如果查詢過程中,不涉及同一事務中多次對資料庫程式設計客棧操作的複雜邏輯及同一事務中多次查詢同一結果集的邏輯,則對速度的提公升效果並不明顯,即事務進行時對資料集加鎖的時間是可以忽略的,下面再來理解一下事務隔離級別與鎖的關係。

談到資料庫隔離級別,就要說一下鎖的概念:

主要分為共享鎖和排他鎖。

共享鎖:由讀表gljpca操作加上的鎖,加鎖後其他使用者只能獲取該錶或行的共享鎖,不能獲取排它鎖,也就是說只能讀不能寫

排它鎖:由寫表操作加上的鎖,加鎖後其他使用者不能獲取該錶或行的任何鎖,典型是mysql事務中。

個人理解:共享鎖和排他鎖沒有嚴格的界限,我認為應該通過結果確定加的是共享鎖還是排他鎖。

例如:使用者a修改一條資料,使用者b也修改這條資料,掛起。 但是b檢視這個資料可以,證明a使用者新增了行級共享鎖。

再例如:使用者a修改一條資料,使用者b查詢這條資料失敗,查詢其他資料也失敗。那麼肯定a加了表級排他鎖。

再例如:使用者a修改一條資料,使用者b查詢記錄可以,但是修改這條記錄不行,修改其他記錄也不行,那麼a加了表級共享鎖。

不同的資料隔離級別,加的鎖是不一樣的。

回到前面的問題,readonly屬性一旦被設定後,資料庫級別如果為提交讀,那麼同乙個事務中,如果對兩次結果集進行查詢,中間間隔修改資料庫,那麼應該會是同乙個結果集,相當於查詢的時候採用的是重複讀的隔離級別。

本文標題: mysql+spring資料庫隔離級別與效能分析

本文位址:

Mysql Spring事務資料整理

可提供的引擎列表 show engines 當前預設儲存引擎 show variables like storage engine 檢視某個錶用了什麼引擎 show create table 表名 select tx isolation 事務隔離級別 髒讀不可重讀 幻讀讀取未提交內容 read un...

隔段時間不登入,資料庫假死

oracle net 12c changes to the functionality of dead connection detection dcd 文件 id 1591874.1 操作 解決一 1 將在客戶端tnsnames.ora中的連線串加入 enable broken 後,問題得到解決 ...

Spring 事務傳播機制和資料庫的事務隔離級別

propagation 事務傳播屬性 類別傳播型別 說明支援當前事務 required 如果當前沒有事務,就新建乙個事務。transaction的預設選擇 支援當前事務 supports 就以非事務的方式執行。支援當前事務 mandatory 如果當前沒有事務,就丟擲異常。不支援當前事務 requi...