spring源碼---事務01

1、什麼情況下回滾

        查看源碼 只有RuntimeException【unchecked Exception】和Error spring事務纔會回滾,對於checked Exception可以通過@Transactional(rollbackFor=Exception.class) 來實現回滾。見Throwable類圖

 2、同一個類中 方法調用事務不起作用

      原因:spring事務 基於aop的 環繞增強實現,通過getBean拿到的是代理對象,執行事務切面,事務切面通過TransactionInterceptor環繞增強進行事務管理,真正執行被增強方法的時候 是被代理對象,也就是下圖中this是OrderTestService而不是代理對象。

      解決方法:A: 直接在當前類@Autowire 或者@Resource 注入自己,然後用注入的bean 調用方法

  

    B:通過ThreadLocal暴露Aop代理對象

實現原理參考:https://blog.csdn.net/JustForSS/article/details/83008824  

具體參考:https://blog.csdn.net/JIESA/article/details/53438342 

3、事務的傳播

@Transactional(value=TxType.REQUIRES_NEW) //暫停當前事務,創建一個新的事務
//    @Transactional(value = TxType.SUPPORTS)//有事務再當前事務中進行 沒有事務 以非事務方式繼續運行
//    @Transactional(value =TxType.NEVER)//非事務的方式運行,存在事務就拋出異常//org.springframework.transaction.IllegalTransactionStateException: Existing transaction found for transaction marked with propagation 'never'
//    @Transactional(value=TxType.NOT_SUPPORTED)//非事務方式運行,存在事務就暫停當前事務,
//    @Transactional(value = TxType.MANDATORY)//以事務方式進行,當前有事務加入當前事務,當前沒有事務 拋出異常 no existing transaction found for transaction marked with propagation mandatory
    @Transactional(value = TxType.REQUIRED)//當前存在事務加入該事務,不存在事務 創建一個新的事務

04、spring的bean的作用域

  • singleton : bean在每個Spring ioc 容器中只有一個實例。可以通過獲取bean比較。缺省值。
  • prototype:一個bean的定義可以有多個實例。
  • request:每次http請求都會創建一個bean,該作用域僅在基於web的Spring ApplicationContext情形下有效。
  • session:在一個HTTP Session中,一個bean定義對應一個實例。該作用域僅在基於web的Spring ApplicationContext情形下有效。
  • global-session:在一個全局的HTTP Session中,一個bean定義對應一個實例。該作用域僅在基於web的Spring ApplicationContext情形下有效。

 

5、spring中bean的聲明週期

  • Spring容器 從XML 文件中讀取bean的定義,並實例化bean。
  • Spring根據bean的定義填充所有的屬性。
  • 如果bean實現了BeanNameAware 接口,Spring 傳遞bean 的ID 到 setBeanName方法。
  • 如果Bean 實現了 BeanFactoryAware 接口, Spring傳遞beanfactory 給setBeanFactory 方法。
  • 如果有任何與bean相關聯的BeanPostProcessors,Spring會在postProcesserBeforeInitialization()方法內調用它們。
  • 如果bean實現InitializingBean了,調用它的afterPropertiesSet方法,如果bean聲明瞭初始化方法,調用此初始化方法。
  • 如果有BeanPostProcessors 和bean 關聯,這些bean的postProcessAfterInitialization() 方法將被調用。
  • 如果bean實現了 DisposableBean,它將調用destroy()方法。

The bean 標籤有兩個重要的屬性(init-method和destroy-method)。用它們你可以自己定製初始化和註銷方法。它們也有相應的註解(@PostConstruct和@PreDestroy)。

 

6、有五種自動裝配的方式,可以用來指導Spring容器用自動裝配方式來進行依賴注入。

  • no:默認的方式是不進行自動裝配,通過顯式設置ref 屬性來進行裝配。
  • byName:通過參數名 自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byname,之後容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。
  • byType::通過參數類型自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byType,之後容器試圖匹配、裝配和該bean的屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。
  • constructor:這個方式類似於byType, 但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。
  • autodetect:首先嚐試使用constructor來自動裝配,如果無法工作,則使用byType方式。

 

7、Spring如何處理線程併發問題?

Spring使用ThreadLocal解決線程安全問題。

我們知道在一般情況下,只有有狀態的Bean纔可以在多線程環境下共享,在Spring中,絕大部分Bean都可以聲明爲singleton作用域。就是因爲Spring對一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全狀態採用ThreadLocal進行處理,讓它們也成爲線程安全的狀態,因爲有狀態的Bean就可以在多線程中共享了。

ThreadLocal和線程同步機制都是爲了解決多線程中相同變量的訪問衝突問題。

(1)在同步機制中,通過對象的鎖機制保證同一時間只有一個線程訪問變量。這時該變量是多個線程共享的,使用同步機制要求程序慎密地分析什麼時候對變量進行讀寫,什麼時候需要鎖定某個對象,什麼時候釋放對象鎖等繁雜的問題,程序設計和編寫難度相對較大。

(2)而ThreadLocal則從另一個角度來解決多線程的併發訪問。ThreadLocal會爲每一個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問衝突。因爲每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。

(3)概括起來說,對於多線程資源共享的問題,同步機制採用了“以時間換空間”的方式,而ThreadLocal採用了“以空間換時間”的方式。前者僅提供一份變量,讓不同的線程排隊訪問,而後者爲每一個線程都提供了一份變量,因此可以同時訪問而互不影響。
 

8、通知有哪些類型?

(1)前置通知(Before advice):在某連接點(join point)之前執行的通知,但這個通知不能阻止連接點前的執行(除非它拋出一個異常)。

(2)返回後通知(After returning advice):在某連接點(join point)正常完成後執行的通知:例如,一個方法沒有拋出任何異常,正常返回。 
(3)拋出異常後通知(After throwing advice):在方法拋出異常退出時執行的通知。 
(4)後通知(After (finally) advice):當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。 
(5)環繞通知(Around Advice):包圍一個連接點(join point)的通知,如方法調用。這是最強大的一種通知類型。 環繞通知可以在方法調用前後完成自定義的行爲。它也會選擇是否繼續執行連接點或直接返回它們自己的返回值或拋出異常來結束執行。 
環繞通知是最常用的一種通知類型。大部分基於攔截的AOP框架,例如Nanning和JBoss4,都只提供環繞通知。
around before 方法執行 around after afterReturing

around before 方法執行 after afterThrowing

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章