最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

探索Java中private方法添加@Transactional事務(wù)未生效原因

 更新時間:2021年11月24日 14:41:05   作者:JavaEdge.  
你又遇到過明明給private方法添加了@Transactional但是事務(wù)依然沒有生效的情況嗎,具體原因本篇文章將詳細(xì)告訴你,有需要的朋友跟著小編往下看吧

現(xiàn)在產(chǎn)品期望用戶創(chuàng)建和保存邏輯分離:把User實例的創(chuàng)建和保存邏輯拆到兩個方法分別進(jìn)行。然后,把事務(wù)的注解 @Transactional 加在保存數(shù)據(jù)庫的方法上。

@Service
public class StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private StudentService studentService;

    public void saveStudent(String realname) throws Exception {
        Student student = new Student();
        student.setRealname(realname);
        studentService.doSaveStudent(student);
    }

    @Transactional
    private void doSaveStudent(Student student) throws Exception {
        studentMapper.saveStudent(student);
        if (student.getRealname().equals("小明")) {
            throw new RuntimeException("該用戶已存在");
        }
    }
}

執(zhí)行程序,異常正常拋出

事務(wù)未回滾

源碼解析

debug:

前一段是 Spring 創(chuàng)建 Bean 的過程。當(dāng) Bean 初始化之后,開始嘗試代理操作,這是從如下方法開始處理的:

AbstractAutoProxyCreator#postProcessAfterInitialization

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

繼續(xù) debug,直到

AopUtils#canApply

針對切面定義里的條件,確定這個方法是否可被應(yīng)用創(chuàng)建成代理。有段 methodMatcher.matches(method, targetClass) 判斷這個方法是否符合這樣的條件:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   // ...
   for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
      for (Method method : methods) {
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }
   return false;
}

從 matches() 調(diào)用到

AbstractFallbackTransactionAttributeSource#getTransactionAttribute

獲取注解中的事務(wù)屬性,根據(jù)屬性確定事務(wù)的策略。

接著調(diào)用到

computeTransactionAttribute

根據(jù)方法和類的類型確定是否返回事務(wù)屬性:

當(dāng)上圖中條件判斷結(jié)果為 true,則返回 null,表明該方法不會被代理,從而導(dǎo)致事務(wù)注解不會生效。

那到底是不是 true 呢?

條件1:allowPublicMethodsOnly()

AnnotationTransactionAttributeSource#publicMethodsOnly屬性值

publicMethodsOnly 是通過 AnnotationTransactionAttributeSource 的構(gòu)造方法初始化的,默認(rèn)為 true。

條件2:Modifier.isPublic()

根據(jù)傳入的 method.getModifiers() 獲取方法的修飾符,該修飾符是 java.lang.reflect.Modifier 的靜態(tài)屬性,對應(yīng)的幾類修飾符分別是:

  • PUBLIC: 1
  • PRIVATE: 2
  • PROTECTED: 4

這里做了一個位運(yùn)算,只有當(dāng)傳入的方法修飾符是 public 類型的時候,才返回 true

綜上兩個條件,只有當(dāng)注解為事務(wù)方法為 public 才會被 Spring 處理。

修正

只需將修飾符從 private 改成 public,其實該問題 IDEA 也會告警,一般都會避免。

調(diào)用這個加了事務(wù)注解的方法,必須是調(diào)用被 Spring AOP 代理過的方法:不能通過類的內(nèi)部調(diào)用或通過 this 調(diào)用。所以我們的案例的StudentService,它Autowired了自身(StudentService)的一個實例來完成代理方法的調(diào)用。

到此這篇關(guān)于探索Java中private方法添加@Transactional事務(wù)未生效原因的文章就介紹到這了,更多相關(guān)Java private方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Cloud Alibaba Nacos Config進(jìn)階使用

    Spring Cloud Alibaba Nacos Config進(jìn)階使用

    這篇文章主要介紹了Spring Cloud Alibaba Nacos Config進(jìn)階使用,文中使用企業(yè)案例,圖文并茂的展示了Nacos Config的使用,感興趣的小伙伴可以看一看
    2021-08-08
  • 完美解決IDEA Ctrl+Shift+f快捷鍵突然無效的問題

    完美解決IDEA Ctrl+Shift+f快捷鍵突然無效的問題

    這篇文章主要介紹了完美解決IDEA Ctrl+Shift+f快捷鍵突然無效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 淺談JavaIO之try with底層原理

    淺談JavaIO之try with底層原理

    眾所周知,所有被打開的系統(tǒng)資源,比如流、文件或者Socket連接等,都需要被開發(fā)者手動關(guān)閉,否則隨著程序的不斷運(yùn)行,資源泄露將會累積成重大的生產(chǎn)事故。本文將介紹JavaIO之try with底層原理。
    2021-06-06
  • 單元測試 @mock與@SpringBootTest的使用

    單元測試 @mock與@SpringBootTest的使用

    這篇文章主要介紹了單元測試 @mock與@SpringBootTest的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java解析excel文件的方法

    java解析excel文件的方法

    這篇文章主要介紹了java解析excel文件的方法,這里整理相關(guān)的代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • Java集合TreeSet用法詳解

    Java集合TreeSet用法詳解

    本文詳細(xì)講解了Java集合TreeSet用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • Java中從Integer到Date的轉(zhuǎn)換方法

    Java中從Integer到Date的轉(zhuǎn)換方法

    這篇文章主要介紹了Java中integer怎么轉(zhuǎn)換date,在Java中,如果我們有一個Integer類型的數(shù)據(jù),想要將其轉(zhuǎn)換為Date類型,本文給大家介紹了實現(xiàn)方法,并通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • Spring自帶定時任務(wù)@Scheduled注解實例講解

    Spring自帶定時任務(wù)@Scheduled注解實例講解

    這篇文章主要介紹了Spring自帶定時任務(wù)@Scheduled注解的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • 盤點(diǎn)SpringBoot中@Async注解的遇到的坑點(diǎn)及解決辦法

    盤點(diǎn)SpringBoot中@Async注解的遇到的坑點(diǎn)及解決辦法

    SpringBoot是一個流行的Java開發(fā)框架,在異步編程方面,Spring Boot提供了@Async注解,它能夠讓方法異步執(zhí)行,然而,在使用@Async注解時,有一些潛在的坑需要注意,本文將深入探討Spring Boot中使用@Async注解時可能遇到的8大坑點(diǎn),并提供相應(yīng)的解決方案
    2024-03-03
  • IntelliJ IDEA中代碼一鍵生成方法

    IntelliJ IDEA中代碼一鍵生成方法

    EasyCode 是基于 IntelliJ IDEA 開發(fā)的代碼生成插件,支持自定義任意模板(Java,html,js,xml),這篇文章主要介紹了IntelliJ IDEA中代碼一鍵生成方法,需要的朋友可以參考下
    2020-02-02

最新評論

康马县| 团风县| 巴马| 于田县| 灵山县| 麻栗坡县| 辽宁省| 莱阳市| 射洪县| 五原县| 偃师市| 怀宁县| 宣城市| 绍兴市| 康乐县| 隆德县| 景洪市| 广昌县| 阜平县| 双柏县| 冀州市| 蕲春县| 泸水县| 星座| 东明县| 朔州市| 神农架林区| 大城县| 含山县| 中宁县| 栖霞市| 沾益县| 镇安县| 沈阳市| 阳朔县| 谢通门县| 辛集市| 文安县| 肥乡县| 康马县| 青河县|