鏈接上文的AOP內容,本文繼續記錄關於AOP的知識點.spring
事務(Transaction)是一個業務,是一個不可分割的邏輯工做單元,基於事務能夠更好的保證業務的正確性數據庫
事務特性:緩存
spring提供了聲明式事務--基於AOP代理,將具體邏輯與事務處理進行解耦.併發
在SpringBoot項目中,其內部提供了事務的自動配置,當咱們在項目中添加了指定依賴spring-boot-starter-jdbc時,框架會自動爲咱們的項目注入事務管理器對象,最經常使用的爲DataSourceTransactionManager對象.框架
spring中最經常使用的是以@Transactional註解形式進行事務管理.異步
基於@Transactional 註解進行聲明式事務管理的實現步驟分爲兩步:ide
@Transactional(timeout = 30, readOnly = false, isolation = Isolation.READ_COMMITTED, rollbackFor = Throwable.class) @Service public class SysUserServiceImpl implements SysUserService{
註解中屬性含義以下:
1)事務屬性timeout的含義是:超時時間,是否容許事務超時,默認不容許(-1),一直等spring-boot
2)事務屬性readOnly的含義是:是否爲只讀事務,(不容許執行更新操做)性能
3)事務屬性rollbackfor的含義是:回滾條件,出現什麼異常事務要回滾spa
norollbackfor: 拋出norollbackfor指定的異常類型,不回滾事務
若是同時寫有rollbackFor和norollbackfor表示除了norollbackfor指定的異常不回滾,rollbackfor指定的都回滾
4)事務屬性isolation的含義是:用於設置隔離級別(多個事務併發處理可能出現-髒讀/不可重複讀/幻讀)
注意:
@Transactional註解既能夠寫在類上也能夠寫在方法上,
當寫在類上表示類中全部方法啓動事務管理,能夠理解爲事務的共性體現;
當寫在方法上表示此方法要進行事務管理,能夠理解爲事務的特性體現;
而且方法上的事務比類上的事務優先級要高!
Spring事務管理是基於接口代理(JDK)或動態字節碼(CGLIB)技術,而後經過AOP實施事務,系統會經過目標對象的代理對象調用DataSourceTransactionManager對象,在事務開始的時,執行doBegin方法,事務結束時執行doCommit或doRollback方法,這裏的方法都是指AOP的通知方法.
事務傳播(Propagation)特性指"不一樣業務(service)對象"中的事務方法之間相互調用時事務的傳播方式
須要注意的是:只有不一樣業務的不一樣方法相互調用纔是傳播特性,同業務內不一樣方法的調用不是.
經常使用的傳播方式有兩種:
1)@Transactional(propagation=Propagation.REQUIRED)
若是沒有事務建立新事務, 若是當前有事務參與當前事務(默認)
如官網中給出的圖所示,在這個調用鏈中三個方法會在事務傳播機制中工做時處於同一個事務中.
2)@Transactional(propagation=Propagation.REQUIRES_NEW)
必須是新事務, 若是有當前事務, 掛起當前事務而且開啓新事務
如官網中給出的圖所示,在這個調用鏈中三個方法會在事務傳播機制中工做時都分別始終處於一個新的事務中.
在開發中一般會考慮系統性能問題-->提高性能一個重要思想就是該串行爲並行-->考慮到並行就離不開異步
分爲兩步:
1)在啓動類上添加註解@EnableAsync-->spring容器啓動時會建立線程池
2)在須要異步執行的業務方法上,使用@Async方法進行異步聲明
@Async描述的方法表示要運行在一個獨立線程中(這個線程由spring框架內置線程池提供);
@Async描述的方法爲一個異步切入點方法(此方法會運行在一個spring框架提供的線程中)
當咱們須要本身對spring框架提供的線程鏈接池進行一些簡易配置:
task: execution: pool: core-size: 10 #定義核心線程數,當池中線程沒有達到這個值時,每來一個任務都會建立一個新的線程 queue-capacity: 256 #任務隊列,當來了新的任務,核心線程都在忙,假如隊列尚未滿,則將任務先扔到隊列 max-size: 256 #當核心線程都在忙,任務隊列也滿了,再來新的任務在建立新的線程,最多能夠建立多少個由這個參數決定 keep-alive: 6000 #當併發訪問高峯期事後,有些線程可能會空閒下來,超過必定的時間,線程要被釋放,這個時間由這個參數決定 thread-name-prefix: cgb-db-thread- #爲池中的線程起個名字前綴
業務方法中咱們可能調用數據層方法獲取數據庫中數據,假如訪問數據的頻率比較高,爲了提升的查詢效率,下降數據庫的訪問壓力,能夠在業務層對數據進行緩存
分爲兩步:
1)在項目(SpringBoot項目)的啓動類上添加@EnableCaching註解,以啓動緩存配置
2)在須要進行緩存的業務方法上經過@Cacheable註解對方法進行相關描述.表示方法的返回值要存儲到Cache中,假如在更新操做時須要將cache中的數據移除,能夠在更新方法上使用@CacheEvict註解對方法進行描述
@Cacheable(value = "menuCache") @Override public List<Map<String, Object>> findObjects() {}
@Cacheable 註解描述的方法爲一個緩存切入點方法,此方法執行以前會從緩存存取數據,緩存沒有數據在從數據庫操做
value屬性的值表示要使用的緩存對象,名字本身指定,其實底層爲一個map對象
@CacheEvict(value = "menuCache",allEntries = true,beforeInvocation = false) @Override public int deleteObject(Integer id) {
@CacheEvict 註解描述的方法也是一個緩存切入點方法,這個方法會在目標方法執行以前或以後執行緩存清除動做,1)value屬性用於指定緩存對象的名稱2)allEntries用於指定是否清除緩存全部數據3)beforeInvocation用於指定清除緩存的動做在目標方法執行以前仍是以後執行,這裏的false表示以後