spring宣告式事務

2021-08-29 02:24:15 字數 4161 閱讀 2695

1. 什麼是事務

事務是程式中一系列嚴密的操作,所有操作執行必須成功完成,否則在每個操作所做的更改將會被撤銷,這也是事務的原子性(要麼成功,要麼失敗)。

2. 事務的特性

事務特性分為四個:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持續性(durability)簡稱acid。

3. 事務的隔離級別

事務的隔離級別也分為四種,由低到高依次分別為:read uncommited(讀未提交)、read commited(讀提交)、read repeatable(讀重複)、serializable(序列化),這四個級別可以逐個解決髒讀、不可重複讀、幻讀這幾類問題。

@transactional(isolation = isolation.read_uncommitted):是最低的事務隔離級別,它允許另外乙個事務可以看到這個事務未提交的資料。

@transactional(isolation = isolation.read_committed):保證乙個事物提交後才能被另外乙個事務讀取。另外乙個事務不能讀取該事物未提交的資料。

@transactional(isolation = isolation.repeatable_read):這種事務隔離級別可以防止髒讀,不可重複讀。但是可能會出現幻象讀。它除了保證乙個事務不能被另外乙個事務讀取未提交的資料之外還避免了以下情況產生(不可重複讀)。

@transactional(isolation = isolation.serializable):這是花費最高代價但最可靠的事務隔離級別。事務被處理為順序執行。除了防止髒讀,不可重複讀之外,還避免了幻象讀。

mysql 預設事務隔離級別:repeatable_read

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

不可重複讀:在同一事務中, 多次讀取同一資料返回的結果有所不同, 換句話說,

後續讀取可以讀到另一事務已提交的更新資料. 相反, "可重複讀"在同一事務中多次

讀取資料時, 能夠保證所讀資料一樣, 也就是後續讀取不能讀到另一事務已提交的更新資料

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

4. spring事務傳播特性

事務傳播行為就是多個事務方法相互呼叫時,事務如何在這些方法間傳播。spring支援7種事務傳播行為:

spring 預設的事務傳播行為是 propagation_required,它適合於絕大多數的情況。假設 servivex#methodx() 都工作在事務環境下(即都被 spring 事務增強了),假設程式中存在如下的呼叫鏈:service1#method1()->service2#method2()->service3#method3(),那麼這 3 個服務類的 3 個方法通過 spring 的事務傳播機制都工作在同乙個事務中。

5.@transactional註解中常用引數說明

引數名稱

功能描述

readonly

該屬性用於設定當前事務是否為唯讀事務,設定為true表示唯讀,false則表示可讀寫,預設值為false。例如:@transactional(readonly=true)

rollbackfor

該屬性用於設定需要進行回滾的異常類陣列,當方法中丟擲指定異常陣列中的異常時,則進行事務回滾。例如:

指定單一異常類:@transactional(rollbackfor=runtimeexception.class)

指定多個異常類:@transactional(rollbackfor=)

rollbackforclassname

該屬性用於設定需要進行回滾的異常類名稱陣列,當方法中丟擲指定異常名稱陣列中的異常時,則進行事務回滾。例如:

指定單一異常類名稱:@transactional(rollbackforclassname=「runtimeexception」)

指定多個異常類名稱:@transactional(rollbackforclassname=)

norollbackfor

該屬性用於設定不需要進行回滾的異常類陣列,當方法中丟擲指定異常陣列中的異常時,不進行事務回滾。例如:

指定單一異常類:@transactional(norollbackfor=runtimeexception.class)

指定多個異常類:@transactional(norollbackfor=)

norollbackforclassname

該屬性用於設定不需要進行回滾的異常類名稱陣列,當方法中丟擲指定異常名稱陣列中的異常時,不進行事務回滾。例如:

指定單一異常類名稱:@transactional(norollbackforclassname=「runtimeexception」)

指定多個異常類名稱:@transactional(norollbackforclassname=)

propagation

該屬性用於設定事務的傳播行為,具體取值可參考表6-7。例如:

@transactional(propagation=propagation.not_supported,readonly=true)

isolation

該屬性用於設定底層資料庫的事務隔離級別,事務隔離級別用於處理多事務併發的情況,通常使用資料庫的預設隔離級別即可,基本不需要進行設定

timeout

該屬性用於設定事務的超時秒數,預設值為-1表示永不超時

注意以下幾點

1、@transactional 只能被應用到public方法上, 對於其它非public的方法,如果標記了@transactional也不會報錯,但方法沒有事務功能.

2、用 spring 事務管理器,由spring來負責資料庫的開啟,提交,回滾.預設遇到執行期例外(throw new runtimeexception(「注釋」);)會回滾,即遇到不受檢查(unchecked)的例外時回滾;而遇到需要捕獲的例外(throw new exception(「注釋」);)不會回滾,即遇到受檢查的例外(就是非執行時丟擲的異常,編譯器會檢查到的異常叫受檢查例外或說受檢查異常)時,需我們指定方式來讓事務回滾要想所有異常都回滾,要加上 @transactional( rollbackfor=) .如果讓unchecked例外不回滾: @transactional(notrollbackfor=runtimeexception.class)

如下:

@transactional

(rollbackfor=exception.

class

)//指定回滾,遇到異常exception時回滾

public

void

methodname()

@transactional

(norollbackfor=exception.

class

)//指定不回滾,遇到執行期例外(throw new runtimeexception("注釋");)會回滾

public itimdaoimpl getitemdaoimpl()

3、@transactional 註解應該只被應用到 public 可見度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @transactional 註解,它也不會報錯, 但是這個被註解的方法將不會展示已配置的事務設定。

4、@transactional 註解可以被應用於介面定義和介面方法、類定義和類的 public 方法上。然而,請注意僅僅 @transactional 註解的出現不足於開啟事務行為,它僅僅 是一種元資料,能夠被可以識別 @transactional 註解和上述的配置適當的具有事務行為的beans所使用。上面的例子中,其實正是 元素的出現 開啟 了事務行為。

5、spring團隊的建議是你在具體的類(或類的方法)上使用 @transactional 註解,而不要使用在類所要實現的任何介面上。你當然可以在介面上使用 @transactional 註解,但是這將只能當你設定了基於介面的**時它才生效。因為註解是不能繼承的,這就意味著如果你正在使用基於類的**時,那麼事務的設定將不能被基於類的**所識別,而且物件也將不會被事務**所包裝(將被確認為嚴重的)。因此,請接受spring團隊的建議並且在具體的類上使用 @transactional 註解。

Spring宣告式事務

net.sf.hibernate.dialect.oracle9dialect false true net.sf.hibernate.transaction.jdbctransactionfactory 1025 用heibernate來管理事務 當用spring和heibernate一起完成da...

Spring 宣告式事務

propagation 事務傳播機制有如下幾種 required 預設值,表示如果存在乙個事務,則支援當前事務 如果沒有事務,則開啟乙個新事務。requires new 表示總是開啟乙個新的事務,如果乙個事務已經存在,則將這個存在的事務掛起,開啟新事務執行該方法。mandatory 表示如果存在乙個...

spring 宣告式事務

資料來源 bean id datasource class org.apache.commons.dbcp.basicdatasource destroy method close property name driverclassname value com.mysql.jdbc.driver p...