偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

[[380009]]

前言

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

事務(wù)的自注入

在 Spring 自調(diào)用事務(wù)失效,你是怎么解決的? 有小伙伴提出可以自己注入自己來(lái)解決事務(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ù)生效了。

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

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

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

異步的自注入

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

NO, NO, NO……

事實(shí)告訴我們是不可以的!

從錯(cuò)誤開始著手:

拋出異常部分 doCreateBean

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

也就是說(shuō)異步的時(shí)候,再次從二級(jí)緩存中獲取的和初始的不相同。

Object earlySingletonReference = getSingleton(beanName, false);

從二級(jí)緩存再次獲取 Bean

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

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

執(zhí)行 singleton.getObject 方法

getEarlyBeanReference

getBeanPostProcessors()

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

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

那就繼續(xù)往下看

到這一步還是正常的

進(jìn)入到 initializeBean 的邏輯,有一部分叫做 applyBeanPostProcessorsAfterInitialization

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

applyBeanPostProcessorsAfterInitialization

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

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

以上也就是為什么 @Async 自調(diào)用不可以,因?yàn)樵诤竺娉跏蓟A段被代理修改了對(duì)象。

@Transactional 為什么可以呢?

getEarlyBeanReference

getBeanPostProcessors()

先判斷 InfrastructureAdvisorAutoProxyCreator true 生成一個(gè)代理對(duì)象。

生成代理對(duì)象

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

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

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

總結(jié)

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

自注入

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

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

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

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

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

 

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

2021-10-18 10:17:07

Go Golang語(yǔ)言

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è)計(jì)模式

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

云計(jì)算云存儲(chǔ)IT

2015-02-27 09:45:25

搶紅包手機(jī)

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

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

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