spring的service類呼叫自己方法事務無效
前言
今天在寫程式碼的時候,遇見了一個非常奇怪的問題,我在spring的一個service方法中呼叫本類中的另一個方法(該方法並不是實現介面來的方法,只是把重複的程式碼抽出來的,只在本類中使用),事務竟然無效。我用的是宣告式事務,之前是直接將註解標註在Controller呼叫的service方法上,由於某種原因,我必須將事務開啟到下面的B方法上,但是將事務移動到B方法上時,事務無效了,大概如下:
TestController.java
package com.ryx.test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class TestController { @Autowired private TestService testService; @RequestMapping("testTransactional") public void testTransactional(){ testService.testTransactional_A(); } }
TestService.java
package com.ryx.test; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class TestService { @Transactional public void testTransactional_A() { System.out.println("這裡是呼叫jdbc存庫"); //這裡是執行另一部分邏輯 testTransactional_B(); } public void testTransactional_B() { //這裡是執行另一部分邏輯 System.out.println("這裡是呼叫jdbc存庫"); } }
之前事務是這樣的,我是將@Transactional 放到了方法A上,方法A是是Controller直接呼叫的方法,方法B也是包含在方法A的事務中,事務是可用的,但是我需要將事務只開在B方法上,A方法不需要開啟事務,然後將@Transactional註解 移到B方法上,事務失效了。
然後搜尋了一下@Transactional註解無效,得到以下有用資訊:
1.在需要事務管理的地方加@Transactional 註解。@Transactional 註解可以被應用於介面定義和介面方法、類定義和類的 public 方法上。
[email protected] 註解只能應用到 public 可見度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 註解,它也不會報錯, 但是這個被註解的方法將不會展示已配置的事務設定。
3.注意僅僅 @Transactional 註解的出現不足於開啟事務行為,它僅僅 是一種元資料。必須在配置檔案中使用配置元素,才真正開啟了事務行為。(spring配置檔案中,開啟宣告式事務)
4.通過 元素的 “proxy-target-class” 屬性值來控制是基於介面的還是基於類的代理被建立。如果 “proxy-target-class” 屬值被設定為 “true”,那麼基於類的代理將起作用(這時需要CGLIB庫cglib.jar在CLASSPATH中)。如果 “proxy-target-class” 屬值被設定為 “false” 或者這個屬性被省略,那麼標準的JDK基於介面的代理將起作用。
5.Spring團隊建議在具體的類(或類的方法)上使用 @Transactional 註解,而不要使用在類所要實現的任何介面上。在介面上使用 @Transactional 註解,只能當你設定了基於介面的代理時它才生效。因為註解是 不能繼承 的,這就意味著如果正在使用基於類的代理時,那麼事務的設定將不能被基於類的代理所識別,而且物件也將不會被事務代理所包裝。
[email protected]的事務開啟 ,或者是基於介面的 或者是基於類的代理被建立。所以在同一個類中一個無事務的方法呼叫另一個有事務的方法,事務是不會起作用的。
看到了最後一條,在同一類中一個呼叫本類中另一個有事務的方法,事務是無效的. 網上也給出瞭解決方法:
1.將這部分業務程式碼寫到另一個service中,然後注入呼叫
2.要呼叫代理類才會被切進去。
那麼應該怎麼做呢?既然只有呼叫代理類的方法才能切入,那我們拿到代理類不就好了嘛。網上說直接通過applicationContext.getBean()可以獲得代理物件,我沒有測試,有想法的可以試一下
我用的另一種方法
第一步:首先在spring的配置檔案中加入以下配置
<!-- 啟用自動代理功能 -->
<aop:aspectj-autoproxy/>
<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true" />
第二步:將之前使用普通呼叫的方法,換成使用代理呼叫((TestService)AopContext.currentProxy()).testTransactional2();
親測單獨在B方法上開啟事務生效!相關推薦
spring的service類呼叫自己方法事務無效
前言今天在寫程式碼的時候,遇見了一個非常奇怪的問題,我在spring的一個service方法中呼叫本類中的另一個方法(該方法並不是實現介面來的方法,只是把重複的程式碼抽出來的,只在本類中使用),事務竟然無效。我用的是宣告式事務,之前是直接將註解標註在Controller呼叫的
類呼叫自己的靜態方法必須把該方法設定為public
否則調用不了 ParaChecker.isOK(bindingResult); public class ParaChecker { static BaseResult paraCheck(BindingResu
獲取呼叫自己方法的使用者的包名和類名
此功能可以獲得第三方的對自己功能的使用情況,可以知道非法操作! //下面程式碼段是獲取呼叫自己方法的人的包名和類名 1.比如一個叫MainActivity內部呼叫了這個初始化 MainActivity中有呼叫:ABC.getInstance(); 結果:name:com.xx.Mai
抽象類呼叫自己的抽象方法,實現來自實現類(很常用)
直接上程式碼 public abstract class Parent { public abstract void dosomething(); public void say(){ dosomething(); Sys
子類實現父類的抽象方法,父類呼叫抽象方法
首先,父類有一個抽象方法,並且在自身的其他方法中呼叫了 public abstract class Baba { public abstract void say(String a); public void dosomething(String a){ say(a); }
關於QWidget的子類呼叫show()方法不能顯示的問題
Qt學了不久,對於它的用法我還不是很熟悉。今天遇到了一個問題:我定義了一個QWidget的子類,程式裡面還有一個主類,主類某一個成員就是QWidget子類的指標,然後用主類去初始化這個指標並呼叫show方法來顯示一些東西,然而這個子類並不能顯示。
關於在Spring 中方法內部呼叫自身方法事務 REQUIRE_NEW 不生效的解釋
開發十年,就只剩下這套架構體系了! >>>
Spring的Service調用本類方法聲明式事務無效的解決方案
{} 解決 ostc oid color wire ont spa 出了 示例: class Test{ public void a(){ b(); } @Transactional pubic void b(){} }
Spring service本類中方法呼叫另一個方法事務不生效問題
前些日子一朋友在需要在目標物件中進行自我呼叫,且需要實施相應的事務定義,且網上的一種通過BeanPostProcessor的解決方案是存在問題的。因此專門寫此篇帖子分析why。 1、預備知識 使用AOP 代理後的方法呼叫執行流程,如圖所示 也就是說我們首先呼叫的是
spring 本類中方法呼叫另外一個方法事務不生效
1、在spring配置檔案中新增 <aop:aspectj-autoproxy expose-proxy="true"/&g
關於呼叫自己寫控制元件庫後,導致主窗體出現索引超範圍,或者值無效等等的問題,以下是解決方法
錯誤如下圖,該錯誤在程式碼中並不會報紅。大家可以看看能否解決。 自定義窗體控制元件,在呼叫的時候會有一個預讀的過程,這個時候如果我們定義下拉選單,如下: comboBox1.Items.Clear(); comboBox1.Items
2.2.1 傳播行為 當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啟一個新事務,並在自己的事務中運行。
相同 comment 自己的 執行 run lose 傳播 tty 可能 2.2.1 傳播行為 當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。例如:方法可能繼續在現有事務中運行,也可能開啟一個新事務,並在自己的事務中運行。 2.2.1 傳播行為 當事務
繼承----super 呼叫父類的相同方法(python)
如果一個子類繼承多個父類,然後呼叫父類的相同的方法,使用__mro__ 可以檢視查詢次序 在python 中 有這樣的機制,如果之前一個父類中的方法呼叫過了,下一次就會繼續往下找,而不是重複呼叫 例項: class A: @classmethod
spring 事務處理中,同一個類中:A方法(無事務)調B方法(有事務),事務不生效問題
public class MyEntry implements IBaseService{ public String A(String jsonStr) throws Exception{ UserInfo user = null; UserDetail userDetail = nul
子函式呼叫父函式,父函式呼叫的方法,子函式重寫了,那麼最後父函式呼叫的是自己的方法,還是子函式的方法。
Q:子類呼叫父類的方法,父類中某個方法所呼叫的方法,子類也重寫了,那麼最後父類中的方法呼叫的是自己的方法,還是子類的方法。 A:呼叫的是子類的方法。 看程式碼: public class Parent { public void used
類和物件 - 方法的呼叫
這個方法呼叫 列印的結果是 1 跟 2 :基本資料型別問題 解:change方法呼叫的時候 傳進去的引數屬於基本資料型別。 change方法在壓站執行的時候 只是重新賦值了 a 跟 b ;main方法執行完change的方法之後
#Java#【1】子類呼叫父類被重寫的方法
一、程式碼 package com.atguigu.exer1; //========== Son =================== public class Son extends Father { public String str = "
java 如何使用多執行緒呼叫類的靜態方法?
1.情景展示 靜態方法內部實現:將指定內容生成圖片格式的二維碼; 如何通過多執行緒實現? 2.分析 之所以採用多執行緒,是為了節省時間 3.解決方案 準備工作 logo檔案 將生成的檔案儲存在F
Android:JNI呼叫C++自定義類的詳細方法
一般情況下,我們都是用 JNI 呼叫 C++ 的某個方法的程式碼,包括直接使用 android studio 生成的程式碼也是如此。但有時我們需要新建、或者得到的是 C++ 的一個自定義類,在呼叫時就不能像呼叫 C++ 方法那樣了,查閱了一部分其他人的部落格,寫的都比較籠統、模糊,對沒接觸過這塊知識
通過反射建立私有化類的物件,呼叫類的私有方法,改變私有屬性
首先建立一個類 public class ReflectDemo { private int m=0; //私有屬性 private ReflectDemo(){ //私有無參建構函式 } public ReflectDemo(int aa