Spring 事務的用法 傳播機制 原理

2021-08-20 20:34:06 字數 3263 閱讀 3407

在乙個業務的實現過程中,可能需要多條sql完成對資料庫的操作,比如賬戶登入,需要匹配使用者名稱和密碼,然後要增加積分,還要記錄登入的ip和時間,這可能需要三個sql語句,這三個語句應當是乙個整體,任意乙個sql執行不成功,都表示這個業務沒有執行完成,這就有了事務的概念。

事務是資料庫中的概念,就是對資料庫的一組操作,由一條或多條sql組成。

事務具有同步的特點,一條sql執行失敗,其他sql都不會執行,即要麼都執行,要麼都不執行。

用start transaction開啟乙個事務,這之後執行的sql語句,在用commit提交事務之前,都沒有被"寫死"到資料庫中,可以用rollback進行回滾操作。

spring在jdbc中提供了乙個事務管理元件:org.springframework.jdbc.datasource.datasourcetransactionmanager

使用事務管理的功能,跟建立bean一樣,可以採用註解和xml配置兩種方式。當然可能還有別的方式,還沒學到

其他:mybatis應該也提供了事務管理的元件

使用註解來實現宣告式事務, 下面詳細說說這個方法:

第一步:引入< tx:>命名空間 ,在spring的配置檔案中修改, beans根元素裡多了三行,如下

xml**

<?xml version="1.0" encoding="utf-8"?>  

第二步:在spring的配置檔案中修改,將所有具有@transactional 註解的bean 自動配置為 宣告式事務支援

第三步: 在介面或類的宣告處 ,寫乙個@transactional. 要是在介面上寫,介面的實現類就會繼承下來.

介面的實現類的具體方法,還可以覆蓋類宣告處的設定.

@transactional  

public class testpoaoimpl extends poaobase implements testpoao

//execute() 方法略...

}

注意的幾點:@transactional 的所有可選屬性如下:

事務的隔離級別 有如下可選:

可以去看spring原始碼 : org.springframework.transaction.annotation.isolation

資料庫提供了四種事務隔離級別, 不同的隔離級別採用不同的鎖類開來實現.

在四種隔離級別中, serializable的級別最高, read uncommited級別最低.

大多數資料庫的預設隔離級別為: read commited,如sql server , oracle.

少數資料庫預設的隔離級別為repeatable read, 如mysql innodb儲存引擎

即使是最低的級別,也不會出現 第一類 丟失 更新問題 .

丟失 更新 :

當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在。最後的更新將重寫由其它事務所做的更新,這將導致資料丟失。   

例:事務a和事務b同時修改某行的值,

1.事務a將數值改為1並提交

2.事務b將數值改為2並提交。

這時資料的值為2,事務a所做的更新將會丟失。

解決辦法:對行加鎖,只允許併發乙個更新事務。

髒讀: 乙個事務讀到另乙個事務未提交的更新資料例:

1.mary的原工資為1000, 財務人員將mary的工資改為了8000(但未提交事務)

2.mary讀取自己的工資 ,發現自己的工資變為了8000,歡天喜地!

3.而財務發現操作有誤,回滾了事務,mary的工資又變為了1000, 像這樣,mary記取的工資數8000是乙個髒資料。

不可重複讀: 在同乙個事務中,多次讀取同一資料,返回的結果有所不同.換句話說就是,後續讀取可以讀到另乙個事務已提交的更新資料. 相反"可重複讀"在同一事務多次讀取資料時,能夠保證所讀資料一樣,也就是後續讀取不能讀到另一事務已提交的更新資料。

例:1.在事務1中,mary 讀取了自己的工資為1000,操作並沒有完成

2.在事務2中,這時財務人員修改了mary的工資為2000,並提交了事務

3.在事務1中,mary 再次讀取自己的工資時,工資變為了2000

解決辦法:如果只有在修改事務完全提交之後才可以讀取資料,則可以避免該問題。

幻讀: 乙個事務讀取到另乙個事務已提交的insert資料.

例:第乙個事務對乙個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時 (此時第一事務還未提交) ,第二個事務向表中插入一行新資料。這時第乙個事務再去讀取表時,發現表中還有沒有修改的資料行,就好象發生了幻覺一樣。

事務的傳播屬性 ,有如下可選

可以去看spring原始碼 : org.springframework.transaction.annotation.propagation

spring事務的本質其實就是資料庫對事務的支援,沒有資料庫的事務支援,spring是無法提供事務功能的。

對於純jdbc運算元據庫,想要用到事務,可以按照以下步驟進行:

使用spring的事務管理功能後,我們可以不再寫步驟 2 和 4 的**而是由spirng 自動完成。那麼spring是如何在我們書寫的crud 之前之後開啟事務 和 關閉事務的呢?解決這個問題,也就可以從整體上理解spring的事務管理實現原理了。下面簡單地介紹下,註解方式為例子:

Spring事務傳播機制

在 spring的 transactiondefinition介面中一共定義了7種事務傳播屬性 propagation required 支援當前事務,如果當前沒有事務,就新建乙個事務。這是最常見的選擇,也是spring事務傳播機制的預設值。propagation supports 支援當前事務,如...

spring事務傳播機制

1.required 必須有乙個事務的支援。如果沒有事務,則新建立乙個,如果有父事務,則使用 fetch 父級事務 2.requires new 必定會建立乙個事務。如果有父事務,則掛起 suspend 父事務,等子事務執行完畢,在恢復 resume 父事務 3.supports 可以有或者沒有事務...

spring事務傳播機制

spring事務傳播機制 propagation required spring預設 如果已經存在事務,那麼加入當前事務,如果不存在事務,則新建事務。總是建立乙個新的事務。新建立事務a,而以前的事務b還在執行。此時有兩個事務,事務a先執行,事務b則被掛起。只有事務a執行完畢後,事務b將繼續執行。ro...