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

2022-07-19 11:51:11 字數 3072 閱讀 8512

spring事務的隔離級別和傳播機制

一、什麼事務

事務就是一系列資料庫操作的序列,這個序列是乙個不可分割的邏輯單元,在其中的操作要麼全部完成,要麼全部無法完成。乙個完整的事務必須滿足

(acid),所謂的acid指的是原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(durability)。

原子性:在乙個事務中的操作都是乙個邏輯的單元,在執行事務序列時,這些操作要麼全部成功,要麼全部失敗。

一致性:對於事務操作,其始終能夠保證在事務操作成功或者失敗回滾時能夠達到一種一致的狀態。

隔離性:各個事務之間的執行是相互不影響。

永續性:事務的永續性指的是事務一旦執行成功,那麼其所做的修改將永久的儲存在資料庫中,此時即使資料庫崩潰,修改的資料也不會丟失。

二、隔離級別問題

髒讀髒讀表示乙個事務能夠讀取另乙個事務中還未提交的資料。比如,某個事務嘗試插入記錄a,此時該事務還未提交,然後另乙個事務嘗試讀取記錄會成功讀取到記錄a的。

幻讀幻讀就是指a事務對所有記錄進行修改,尚未提交,此時b事務建立了一條新記錄,a、b都提交。a檢視所有資料,發現有一條資料沒有被修改,因新增的,就想看到了幻象一樣。

不可重複讀

不可重複度指a事務對一條記錄進行修改,尚未提交,b事務第一次查詢該記錄,看到的是修改之後的結果,此時a發生回滾,b事務又一次查詢該記是回滾後的結果。同乙個事務內,b兩次查詢結果不一致。

三、事務隔離級別

事務隔離級別就是為了解決髒讀、幻讀、不可重複讀著這幾個問題而產生的,但是事務隔離級別不同,產生的問題也不同,因此很多時候必須在併發性乙個權衡,所以設立了幾種事務隔離級別,以便讓不同的專案可以根據自己專案的併發情況選擇合適的事務隔離級別。事務隔離級別預設又四種,不過種:

1. default:預設隔離級別,每種資料庫支援的事務隔離級別不一樣,oracle預設(讀已提交) mysql預設(可重複讀)。

2. read_uncommitted:讀未提交,即能夠讀取到沒有被提交的資料,這是隔離性最低的一種隔離級別,無法解決髒讀、不可重複讀、幻讀問題

3. read_commited:讀已提交,即能夠讀到那些已經提交的資料,能夠防止髒讀,避免不了幻讀和不可重複讀。

4. repeatable_read:可重複讀,解決髒讀和不可重複讀的問題,但是其無法解決幻讀。

5. serlalizable:序列化,提供嚴格的事務隔離。它要求事務序列化執行,事務只能乙個接著乙個地執行,但不能併發執行,故此效能很低

四、事務傳播機制

1. propagation_required:支援當前事務,如果當前沒有事務,就新建乙個事務。這是最常見的選擇,也是 spring 預設的事務的傳播。

2. propagation_requires_new:新建事務,如果當前存在事務,把當前事務掛起。

3. propagation_supports:支援當前事務,如果當前沒有事務,就以非事務方式執行。

4. propagation_mandatory:使用當前的事務,如果當前沒有事務,就丟擲異常。

5. propagation_not_supported:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

6. propagation_never:以非事務方式執行,如果當前存在事務,則丟擲異常。

7. propagation_nested:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行與propagation_required類似的操作

五、事務唯讀屬性

spring事務唯讀的含義是指,如果後端資料庫發現當前事務為唯讀事務,那麼就會進行一系列的優化措施。它是在後端資料庫進行實施的,因此,只有可能啟動乙個新事務的傳播行為(required,requires_new,nested)的方法來說,才有意義。

六、事務超時

有的時候為了系統中關鍵部分的效能問題,它的事務執行時間應該盡可能的短。因此可以給這些事務設定超時時間,以秒為單位。我們知道事務的發生資料庫的表鎖或者被資料庫優化為行鎖,如果允許時間過長,那麼這些資料會一直被鎖定,影響系統的併發性。因為超時時鐘是在事務開始的時候啟動,因此只有對於那些有可能啟動新事物的傳播行為(required,requires_new,nested)的方法來說,意義。

七、事務回滾規則

spring中可以指定當方法執行並丟擲異常的時候,哪些異常回滾事務,哪些異常不回滾事務。預設情況下,只在方法丟擲執行時異常的時候才回滾(ruexception)。而在出現受阻異常(checked exception)時不回滾事務。當然可以採用申明的方式指定哪些受阻異常像執行時異常那樣指定事務回滾。

簡單來說#{}會在將引數加上引號,例如:

select * from user where username=# ;

帶上引數後的sql語句即:

select * from user where username="xulitong" ;

而${}

並不會在給引數加上引號,例如:

select * from user order by $ desc limit #,#;

帶上引數後的sql語句為:

select * from user order by id desc limit 0,10;

可見,mybatis對引數沒有進行任何的處理,際應用中,並不提倡使用 ${},因為使用 #{} 寫法,除了可以防止sql注入以外,還能在引數裡含有單引號的時候自動轉義。

spring事務隔離級別

在spring中定義了5中不同的事務隔離級別 1.isolation default 一般情況下使用這種配置既可 這是乙個platfromtransactionmanager預設的隔離級別,使用資料庫預設的事務隔離級別。2.isolation read uncommitted 4 p l.i f k...

Spring 事務隔離級別

資料庫事務的隔離級別有4種,由低到高分為為read uncomitted,read comitted,repeatable read serializable,而且,在事務的併發操作中可能會出現髒讀,不可重複度,虛讀 幻讀 髒讀 read uncomitted 什麼都防不住 乙個事務讀到另外乙個事務...

Spring事務隔離級別

事務操作可能出現的問題 更新丟失 lost update 當系統允許兩個事務同時更新同一資料時,發生更新丟失。髒讀 dirty read 當乙個事務讀取另乙個事務尚未提交的修改時,產生髒讀。非重複讀 nonrepeatable read 第一次讀 得到乙個結果 再讀,換了乙個結果 幻像 phanto...