Spring,為內部方法新起乙個事務,此處應有坑

2021-08-09 07:09:03 字數 3028 閱讀 2524

事務的作用,使我們操作能夠連貫起來。而spring則是提供了乙個更簡單的方法,只要使用 @transactional 乙個註解,就可以保證操作的連貫性了。

普通用法,稍後再說,這裡要說的是: 在最外面的方法中,有乙個@transactional 的註解,當有丟擲異常時,則進行回滾操作:

@transactional(readonly = false, rollbackfor = throwable.class, isolation = isolation.repeatable_read)

原本這個方法執行得好好的,但是有一天,我們需要在這個方法裡新增乙個新業務操作,而且這個業務操作是不要求回滾的,類似於做日誌記錄一類的。what should i do ?

由於業務的獨特性,我能夠快速想到的是,在這個類裡面加乙個private方法,然後直接去呼叫就ok了,如果說還是考慮到回滾的話,我也快速想到 @transactional 的not_supported傳播特性,如:

@transactional(propagation = propagation.not_supported)

private void domyexjob(userdebitcardbean userdebitcard)

這看起來很合理,沒毛病。

然而就是執行不起來,只要外面呼叫的方法一丟擲異常,那麼這個新方法的資料操作將會被回滾。媽蛋,到底**出了問題???仔細查了下資料,原來 @transactional 註解由於原理決定了他只能作用於public方法中,而這裡改為private,就完全被忽略無視了。ok,改唄:

@transactional(propagation = propagation.not_supported)

public void domyexjob(userdebitcardbean userdebitcard)

感覺應該好了,然而並沒有。我也是醉了,這個問題,如果仔細花時間,找原理是沒有問題的,但是在關鍵時刻來這麼一下,還是很不爽的。 網上看到一哥們說,還必須要將方法寫到另乙個類中,而且要通過spring的注入方式進行呼叫,才可以。好吧,那我就按照他的來,結果真的成功了。

//在介面中進行了定義,能夠注入

@override

@transactional(propagation = propagation.not_supported)

public void domyexjob(userdebitcardbean userdebitcard)

總算可以了,在趕時間的時候,能夠解決問題的,就是好方法。至此,問題解決。1. 使用public訪求;2. 寫在外部類中,可被呼叫; 3. 使用注入的方式進行該方法的執行。

說實話,spring這種事務還是有點不太好用的,要求太多,當然了,有很大部分原因是我沒有理解其精髓。ok,下面我們來看看spring事務的講解:

在配置檔案中,預設情況下,會自動使用名稱為transactionmanager的事務管理器。所以,如果定義的事務管理器名稱為transactionmanager,那麼就可以直接使用。如下:

class="org.springframework.jdbc.datasource.datasourcetransactionmanager"

p:datasource-ref="datasource">

一共有四個屬性如下,

@transactional的屬性

isolation 列舉org.springframework.transaction.annotation.isolation的值 事務隔離級別

norollbackfor class<? extends throwable> 一組異常類,遇到時不回滾。預設為{}

norollbackforclassname stirng 一組異常類名,遇到時不回滾,預設為{}

propagation 列舉org.springframework.transaction.annotation.propagation的值 事務傳播行為

readonly boolean 事務讀寫性

rollbackfor class<? extends throwable> 一組異常類,遇到時回滾

rollbackforclassname stirng 一組異常類名,遇到時回滾

timeout int 超時時間,以秒為單位

value string 可選的限定描述符,指定使用的事務管理器

@transactional標註的位置

@transactional註解可以標註在類和方法上,也可以標註在定義的介面和介面方法上。

如果我們在介面上標註@transactional註解,會留下這樣的隱患:因為註解不能被繼承,所以業務介面中標註的@transactional註解不會被業務實現類繼承。所以可能會出現不啟動事務的情況。所以,spring建議我們將@transaction註解在實現類上。

在方法上的@transactional註解會覆蓋掉類上的@transactional。

注意:

@transactional 可以作用於介面、介面方法、類以及類方法上。當作用於類上時,該類的所有 public 方法將都具有該型別的事務屬性,同時,我們也可以在方法級別使用該標註來覆蓋類級別的定義。

雖然 @transactional 註解可以作用於介面、介面方法、類以及類方法上,但是 spring 建議不要在介面或者介面方法上使用該註解,因為這只有在使用基於介面的**時它才會生效。另外, @transactional 註解應該只被應用到 public 方法上,這是由 spring aop 的本質決定的。如果你在 protected、private 或者預設可見性的方法上使用 @transactional 註解,這將被忽略,也不會丟擲任何異常。

預設情況下,只有來自外部的方法呼叫才會被aop**捕獲,也就是,類內部方法呼叫本類內部的其他方法並不會引起事務行為,即使被呼叫方法使用@transactional註解進行修飾。

返回乙個參考的內部

我們把值時 smyarray,10 value 返回乙個參考的內部smyarray陣列第十元素。main 然後使用這些參考指定元素的值5。雖然這是有點做作的例子 因為你可以直接訪問smyarray.anvalue 一旦你了解課程你將發現更多的用途,通過引用返回值。返回位址 返回的返回位址到位址的變數...

為乙個HTML文件應用CSS的方法

為html文件應用css,有三種方法可供選擇。下面對這三種方法進行了概括。我們建議你對第三種方法 即外部樣式表 予以關注。為html應用css的一種方法是使用html屬性style。我們在上例的基礎之上,通過行內樣式表將頁面背景設為紅色 這個頁面是紅色的 為html應用css的另一種方法是採用htm...

js判斷乙個物件為陣列的方法

陣列物件js的陣列是無型別的 陣列元素可以是任意型別,並且同乙個陣列中的不同元素也可能有不同的型別。陣列的元素可以是物件或其他陣列,這樣就可以建立複雜的資料結構。通常我們可以用一元運算子typeof來判斷js的資料型別,但是對於陣列這樣乙個特殊的物件卻只能返回 object typeof 1,2,3...