Ⅰ spring—AOP與事務
title: spring——AOP與事務.md
date: 2020-07-14 13:10:16
categories: [Spring]
tags: [AOP,事務]
toc: true
先列出源碼中比較重點的幾個類:
1、<aop:before method="before" pointcut-ref="myMethods"/>包裝成一個advisor
2、,當實例化所有bean都會執行到類
它會檢測bean是否advisor以及advice存在,如果有就說明這個bean有切面,有切面那麼就會生成代理
3、jdk的代理,bean裡面的所有advisor加入到proxyFactory。
4、jdkDynamicProxy invoke,拿到bean裡面的所有Interceptor,會循環proxyFactory裡面的所有advisor
裡面有advice,裡面的advice有兩種類型,要麼是advice,要麼是MethodInterceptor類型的
5、當代理對象調用方式,是一個MethodInterceptor類型的類的鏈式調用過程,直到容器的大小和索引一致的時候調用JoinPoint目標方法
before:this.advice.before(),invocation.processd();
裝配參數,切面裡面before方法的method對象,method.getParamterTypes()[0]
最終會把advice封裝成MethodInterceptor類型的對象
程序執行的某個特定位置:如類開始初始化前、類初始化後、類某個方法調用前、調用後、方法拋出異常後。一個類或一段程序代碼擁有一些具有邊界性質的特定點,這些點中的特定點就稱為「連接點」。Spring僅支持方法的連接點,即僅能在方法調用前、方法調用後、方法拋出異常時以及方法調用前後這些程序執行點織入增強。連接點由兩個信息確定:第一是用方法表示的程序執行點;第二是用相對點表示的方位。
每個程序類都擁有多個連接點,如一個擁有兩個方法的類,這兩個方法都是連接點,即連接點是程序類中客觀存在的事物。AOP通過「切點」定位特定的連接點。連接點相當於資料庫中的記錄,而切點相當於查詢條件。切點和連接點不是一對一的關系,一個切點可以匹配多個連接點。在Spring中,切點通過org.springframework.aop.Pointcut介面進行描述,它使用類和方法作為連接點的查詢條件,Spring AOP的規則解析引擎負責切點所設定的查詢條件,找到對應的連接點。其實確切地說,不能稱之為查詢連接點,因為連接點是方法執行前、執行後等包括方位信息的具體程序執行點,而切點只定位到某個方法上,所以如果希望定位到具體連接點上,還需要提供方位信息。
增強是織入到目標類連接點上的一段程序代碼,在Spring中,增強除用於描述一段程序代碼外,還擁有另一個和連接點相關的信息,這便是執行點的方位。結合執行點方位信息和切點信息,我們就可以找到特定的連接點。
增強邏輯的織入目標類。如果沒有AOP,目標業務類需要自己實現所有邏輯,而在AOP的幫助下,目標業務類只實現那些非橫切邏輯的程序邏輯,而性能監視和事務管理等這些橫切邏輯則可以使用AOP動態織入到特定的連接點上。
引介是一種特殊的增強,它為類添加一些屬性和方法。這樣,即使一個業務類原本沒有實現某個介面,通過AOP的引介功能,我們可以動態地為該業務類添加介面的實現邏輯,讓業務類成為這個介面的實現類。
織入是將增強添加對目標類具體連接點上的過程。AOP像一台織布機,將目標類、增強或引介通過AOP這台織布機天衣無縫地編織到一起。根據不同的實現技術,AOP有三種織入的方式:
a、編譯期織入,這要求使用特殊的Java編譯器。
b、類裝載期織入,這要求使用特殊的類裝載器。
c、動態代理織入,在運行期為目標類添加增強生成子類的方式。
Spring採用動態代理織入,而AspectJ採用編譯期織入和類裝載期織入。
一個類被AOP織入增強後,就產出了一個結果類,它是融合了原類和增強邏輯的代理類。根據不同的代理方式,代理類既可能是和原類具有相同介面的類,也可能就是原類的子類,所以我們可以採用調用原類相同的方式調用代理類。
切面由切點和增強(引介)組成,它既包括了橫切邏輯的定義,也包括了連接點的定義,Spring AOP就是負責實施切面的框架,它將切面所定義的橫切邏輯織入到切面所指定的連接點中。
advisor: pointCut advice
一類功能的增強
around方法裡面代碼切面
事務切面
緩存切面
日誌切面
事務(Transaction),一般是指要做的或所做的事情。在計算機術語中是指訪問並可能更新資料庫中各種數據項的一個程序執行單元(unit)。是資料庫操作的最小工作單元,是作為單個邏輯工作單元執行的一系列操作;這些操作作為一個整體一起向系統提交,要麼都執行、要麼都不執行;事務是一組不可再分割的操作集合(工作邏輯單元)。
大致流程形如
資料庫事務擁有幾大特性:
事務的四大特性:
事務是資料庫的邏輯工作單位,事務中包含的各操作要麼都做,要麼都不做
事 務執行的結果必須是使資料庫從一個一致性狀態變到另一個一致性狀態。因此當資料庫只包含成功事務提交的結果時,就說資料庫處於一致性狀態。如果資料庫系統 運行中發生故障,有些事務尚未完成就被迫中斷,這些未完成事務對資料庫所做的修改有一部分已寫入物理資料庫,這時資料庫就處於一種不正確的狀態,或者說是 不一致的狀態。
一個事務的執行不能其它事務干擾。即一個事務內部的操作及使用的數據對其它並發事務是隔離的,並發執行的各個事務之間不能互相干擾。
也稱永久性,指一個事務一旦提交,它對資料庫中的數據的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。
個人理解,事務在Spring中是藉助AOP技術來實現的,可以作為AOP中的一個事務切面。spring源碼對事務的處理邏輯,自己研究吧!
ORM框架中以Mybatis為例,事務處理就是用到了一個類Transaction,部分源碼如下
可以看出Transaction管理的就是一個connection,而connection我們很清楚是與用戶會話掛鉤的。
那麼關系就是Transaction 管理Connection ,而connection與 用戶session一對一存在。
在springBoot中,只需要加入POM就可以了,配合註解使用即可。
接下來就是事務的控制了。
首先事務有幾大傳播屬性:
其中最常見的,用得最多就 PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、 PROPAGATION_NESTED 這三種。事務的傳播屬性是 spring 特有的,是 spring 用來控制方法事務的一種手段,說直白點就是用來控制方法是否使用同一事務的一種屬性,以及按照什麼規則回滾的一種手段。
下面用代碼演示這三種屬性的機制:
事務的默認屬性就是required,通過Transactional.java中的Propagation propagation() default Propagation.REQUIRED; 可以看出。
這種情況就是事務1,事務2 都加入到了事務0中。不管是1,2哪個事務拋出異常,事務0都會回滾。數據添加會失敗。
這種情況就是:
事務0(required) {
事務1 (REQUIRES_NEW)
事務2
}
此時。
情況a:
1、如果只是事務2出現了異常,那麼事務1會提交,事務2加入到事務0中會回滾。
2、如果只是事務1出現了異常,那麼事務1會回滾,向上層事務0拋異常,事務2會加入到事務0中,這時都會回滾。
情況b:
如果事務1,事務2都是REQUIRES_NEW傳播屬性。那麼結果就是:
1、如果事務1,拋出了異常,那麼事務2是不會執行的,那麼事務0必然回滾。
2、如果事務2,拋出異常,那麼事務1會提交,表中會有數據。事務2有異常回滾並拋出,事務0回滾。
NESTED屬性其實就是創建了回滾點,有異常時,會回滾到指定的回滾點。
在這通過代碼測試,出現一種情況是,無論事務1,事務2哪個有異常,數據都不會插入成功,原因是,不論是事務1還是事務2都會向事務0拋出異常,事務0捕獲到異常後,執行rollback()方法,這就操作成了,事務的全部回滾。
如果想要事務1和事務2 想要根據自己的回滾點回滾,那麼事務0必須自己處理異常,不讓spring捕獲到這個異常,那麼就滿足了。把代碼改成這種:
Jack大佬提供了,偽代碼分析法。
按照Spring源碼的事務處理邏輯,偽代碼大致為:
Ⅱ 聲明式 跟spring aop管理事務有什麼不同
聲明式就是提前指派,在為某些包,類,方法,指定好受事物管理,需要再配置文件中配置
編程式就是程序員在程序里自由發揮,啟動事物管理了,aop是面向切面編程,把程序執行的過程看成一條連貫的線,aop就是在指定的點切一刀,凡是經過這點的操作都必須先執行aop定義好的操作,好處就是在不影響原程序的情況下,方便的加入或刪除附加的邏輯處理操作,比如日誌記錄,許可權控制等
編程式事務與聲明式事務的區別是什麼?
編程式事務是自己寫事務處理的類,然後調用
聲明式事務是在配置文件中配置,一般搭配在框架裡面使用!
聲明式事務
聲明式事務(declarative transaction management)是Spring提供的對程序事務管理的方式之一。
Spring的聲明式事務顧名思義就是採用聲明的方式來處理事務。這里所說的聲明,就是指在配置文件中申明。用在Spring配置文件中聲明式的處理事務來代替代碼式的處理事務。這樣的好處是,事務管理不侵入開發的組件,具體來說,業務邏輯對象就不會意識到正在事務管理之中,事實上也應該如此,因為事務管理是屬於系統層面的服務,而不是業務邏輯的一部分,如果想要改變事務管理策劃的話,也只需要在定義文件中重新配置即可;在不需要事務管理的時候,只要在設定文件上修改一下,即可移去事務管理服務,無需改變代碼重新編譯,這樣維護起來極其方便。
Spring使用AOP來完成聲明式的事務管理,因而聲明式事務是以方法為單位,Spring的事務屬性自然就在於描述事務應用至方法上的策略,在Spring中事務屬性有以下四個參數:
1.傳播行為
2.隔離級別
3.只讀提示
4.事務超時期間