成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring 事務(wù)、異步和循環(huán)依賴有什么關(guān)系?

開發(fā) 前端
在循環(huán)依賴中有一種循環(huán)依賴,就是自注入:自己依賴自己。在 Spring 自調(diào)用事務(wù)失效,你是怎么解決的? 有小伙伴提出可以自己注入自己來解決事務(wù)失效。

[[380009]]

前言

在循環(huán)依賴中有一種循環(huán)依賴,就是自注入:自己依賴自己。

事務(wù)的自注入

在 Spring 自調(diào)用事務(wù)失效,你是怎么解決的? 有小伙伴提出可以自己注入自己來解決事務(wù)失效。

具體使用方式如下:

  1. @Slf4j 
  2. @Service 
  3. public class OrderBizServiceImpl implements OrderBizService { 
  4.  
  5.     // 注入自己 
  6.     @Autowired 
  7.     private OrderBizService orderBizService; 
  8.  
  9.     @Override 
  10.     public void callBack() throws Exception { 
  11.  
  12.         // 一系列的邏輯 
  13.  
  14.         // 需要事務(wù)操作更新訂單和用戶金額 
  15.         orderBizService.updateOrderStatusAndUserBalance(); 
  16.     } 
  17.  
  18.     @Override 
  19.     @Transactional(rollbackFor = Exception.class) 
  20.     public void updateOrderStatusAndUserBalance() throws Exception { 
  21.         // 內(nèi)部是事務(wù)邏輯 
  22.     } 

是不是發(fā)現(xiàn)很神奇的事情,事務(wù)生效了。

其實這里注入自己,其實是注入的一個代理對象,調(diào)事務(wù),也是調(diào)的代理對象的事務(wù),所以事務(wù)生效。

Spring 事務(wù)失效原因:

事務(wù)只能應(yīng)用到 public 方法上才會有效;事務(wù)需要從外部調(diào)用,Spring 自調(diào)用會失效;建議事務(wù)注解 @Transactional 一般添加在實現(xiàn)類上。

異步的自注入

發(fā)現(xiàn) @Transactional 注解可以自注入解決事務(wù)失效的問題,在某次開發(fā)中,自然而然想到 @Async 異步是不是也可以自注入解決循環(huán)依賴的問題。

NO, NO, NO……

事實告訴我們是不可以的!

從錯誤開始著手:

拋出異常部分 doCreateBean

開始往上面反推 exposedObject == bean 是這一塊出了問題。

也就是說異步的時候,再次從二級緩存中獲取的和初始的不相同。

Object earlySingletonReference = getSingleton(beanName, false);

從二級緩存再次獲取 Bean

這一次獲取的時候發(fā)現(xiàn)不同所以報錯。

那就開始 Debug, 按照循環(huán)依賴的邏輯,執(zhí)行到 populateBean 時,屬性賦值,發(fā)現(xiàn)有依賴自己,此時會創(chuàng)建自己。

執(zhí)行 singleton.getObject 方法

getEarlyBeanReference

getBeanPostProcessors()

而此時執(zhí)行 getEarlyBeanReference 先判斷 InfrastructureAdvisorAutoProxyCreator true 調(diào)用 wrapIfNecessary 判斷是否生成一個代理對象,這里并沒有生成代理對象。

然后開始執(zhí)行異步的 AsyncAnnotationBeanPostProcessor 判斷為 false。所以沒有執(zhí)行異步的生成代理對象邏輯。

那就繼續(xù)往下看

到這一步還是正常的

進入到 initializeBean 的邏輯,有一部分叫做 applyBeanPostProcessorsAfterInitialization

方面小伙伴搜索,所以貼出來代碼關(guān)鍵字。IDEA 使用 ? + Shift + F 搜索。

applyBeanPostProcessorsAfterInitialization

循環(huán)執(zhí)行后置處理器:

發(fā)現(xiàn)執(zhí)行完 AsyncAnnotationBeanPostProcessor 這個 PostProcessor 后,對象被改變了。從而導(dǎo)致二級緩存和當前的 Bean 不同。

以上也就是為什么 @Async 自調(diào)用不可以,因為在后面初始化階段被代理修改了對象。

@Transactional 為什么可以呢?

getEarlyBeanReference

getBeanPostProcessors()

先判斷 InfrastructureAdvisorAutoProxyCreator true 生成一個代理對象。

生成代理對象

事務(wù)的處理器 PersistenceExceptionTranslationPostProcessor 也沒有執(zhí)行。

繼續(xù) Debug 關(guān)注 applyBeanPostProcessorsAfterInitialization

執(zhí)行結(jié)束,發(fā)現(xiàn) Bean 沒有發(fā)生改變。

總結(jié)

  • @Transactional: 是在循環(huán)依賴從二級緩存升到三級緩存的時候已經(jīng)生成了代理對象。
  • @Async: 是在初始化階段(initializeBean)去生成代理對象。然后 @Async 導(dǎo)致后面判斷 exposedObject == bean 為 false ,從而拋出異常。

自注入

可以看出圖中有兩處會執(zhí)行 BeanPostProcessor :

  1. 在 singletonFactory.getObject 時,如果是 SmartInstantiationAwareBeanPostProcessor 的子類會執(zhí)行 getEarlyBeanReference 方法。
  2. 在 initializeBean 的 applyBeanPostProcessorsAfterInitialization 時會執(zhí)行所有 BeanPostProcessor 的 postProcessAfterInitialization 的方法。

也有其他的地方在執(zhí)行后置處理器,比如 applyBeanPostProcessorsBeforeInitialization ,只不過這里關(guān)注這倆處。

而這兩處都有可能生成代理對象, @Transactional 是在 getEarlyBeanReference 處生成的代理對象,所以后面判斷 Bean 是否被改變時為 true,而 @Async 是在后面異步生成了代理對象,所以判斷不通過。

本文轉(zhuǎn)載自微信公眾號「程序員小航」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系程序員小航公眾號。

 

責(zé)任編輯:武曉燕 來源: 程序員小航
相關(guān)推薦

2021-10-18 10:17:07

Go Golang語言

2019-09-29 19:28:13

區(qū)塊鏈比特幣加密貨幣

2021-04-27 10:14:28

大數(shù)據(jù)物聯(lián)網(wǎng)IOT

2015-08-27 14:05:01

大數(shù)據(jù)創(chuàng)業(yè)

2020-02-27 08:52:51

NFVSDN網(wǎng)絡(luò)

2022-11-01 15:02:11

2023-11-02 09:59:53

C++設(shè)計模式

2022-02-14 11:28:51

區(qū)塊鏈元宇宙代幣

2021-07-20 08:12:55

CPU核數(shù)線程數(shù)

2012-09-03 09:58:09

2018-03-18 07:44:47

云計算云存儲IT

2015-02-27 09:45:25

搶紅包手機

2023-04-06 11:54:55

2024-03-10 21:00:33

2022-06-18 23:10:56

前端模塊循環(huán)依賴

2023-07-10 10:53:22

2023-05-04 08:06:27

Spring循環(huán)依賴

2017-12-10 22:19:30

2022-07-06 08:36:34

threadpromise

2020-04-30 11:05:50

機器閱讀人工智能機器學(xué)習(xí)
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 日韩中文字幕一区 | 欧美精品综合在线 | 国产一区二区三区四区 | 性色av一区二区三区 | 日本一二区视频 | 精品一级电影 | 中文字幕第十页 | 一区二区三区免费网站 | 久产久精国产品 | 中文字幕二区三区 | 国产精品国产a | 97在线观看| 国产精品一区在线观看你懂的 | 久久美女网 | 2020国产在线| 一区二区三区免费在线观看 | 亚洲成人精品久久久 | 黄色免费av | 国产精品永久免费视频 | 免费小视频在线观看 | 国产午夜久久 | 中文字幕欧美日韩一区 | 亚洲精品黄 | 久久综合av | 在线视频一区二区 | 网站黄色在线免费观看 | 日韩免费视频一区二区 | 国产乱码精品一区二区三区中文 | 国产在线中文字幕 | 精品视频一区二区三区在线观看 | 精品一区电影 | 免费在线观看av网站 | 中文日韩字幕 | 欧美日韩国产一区二区 | 国产精品激情 | 欧美精品一区二区三区视频 | 成人午夜精品 | 日韩精品免费视频 | 91婷婷韩国欧美一区二区 | 欧美精品一区二区蜜桃 | 成人一区在线观看 |