1. 程式人生 > >資料庫事物隔離級別設定(針對多執行緒)

資料庫事物隔離級別設定(針對多執行緒)

資料庫的髒讀、不可重複讀、幻讀都和事務的隔離性有關。所以先了解一下事務的4大特性。 

事務的4大特性(ACID):

原子性(Atomicity):事務是資料庫的邏輯工作單位,它對資料庫的修改要麼全部執行,要麼全部不執行,通俗點就是開啟了一個事物,那麼這個事物內的所有操作(增刪改sql),只有事物提交了,這些操作對資料庫中的資料才起作用。 

一致性(Consistemcy):事務前後,資料庫的狀態都滿足所有的完整性約束,通俗點就是如果事物提交後得到的結果是一樣的,那麼事物中間不論有多少操作(多少個增刪改),事物保證我們最終要的結果是一樣的。 

隔離性(Isolation):併發執行的N個事務是隔離的,一個不影響一個,一個事務在沒有commit之前,被修改的資料不可能被其他事務看到(通過設定資料庫的隔離級別)。 

永續性(Durability):永續性意味著當系統或介質發生故障時,確保已提交事務的更新不能丟失。永續性主要在於DBMS的恢復效能。

那麼事物的隔離性可能導致一下問題的發生:

1,髒讀

  髒讀是指在一個事務處理過程裡讀取了另一個未提交的事務中的資料。

2,不可重複讀

  不可重複讀是指在對於資料庫中的某個資料,一個事務範圍內多次查詢卻返回了不同的資料值,這是由於在查詢間隔,被另一個事務修改並提交了。

3,虛讀(幻讀)

  幻讀是事務非獨立執行時發生的一種現象。例如事務T1對一個表中所有的行的某個資料項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行資料項,而這個資料項的數值還是為“1”並且提交給資料庫。而操作事務T1的使用者如果再檢視剛剛修改的資料,會發現還有一行沒有修改,其實這行是從事務T2中新增的,就好像產生幻覺一樣,這就是發生了幻讀。

  幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個資料項,而幻讀針對的是一批資料整體(比如資料的個數)。

那麼怎麼解決這些問題呢,我們可以通過給資料庫設定隔離級別來有效的解決這些問題

    現在來看看MySQL資料庫為我們提供的四種隔離級別:

  ① Serializable (序列化):可避免髒讀、不可重複讀、幻讀的發生。

  ② Repeatable read (可重複讀):可避免髒讀、不可重複讀的發生。

  ③ Read committed (讀已提交):可避免髒讀的發生。

  ④ Read uncommitted (讀未提交):最低級別,任何情況都無法保證。

mysql檢視事物隔離級別的sql: select @@tx_isolation;

mysql設定隔離級別的sql:set tx_isolation='事物隔離級別名稱';

當然也可以通過jdbc來設定:如果是使用JDBC對資料庫的事務設定隔離級別的話,也應該是在呼叫Connection物件的setAutoCommit(false)方法之前。

呼叫Connection物件的setTransactionIsolation(level)即可設定當前連結的隔離級別

注:隔離級別越高,執行效率越差;資料庫避免髒讀的做法是通過鎖表來實現的。