spring源碼 — 5、事務

spring提供了可配置、易擴展的事務處理框架,本文主要從一下幾個方面說明spring事務的原理java

  • 基本概念
  • 事務配置解析
  • 事務處理過程

基本概念

事務隔離級別

在同時進行多個事務的時候,可能會出現髒讀、不可重複讀、幻讀四種狀況,數據庫分別有四種隔離級別處理這些狀況。Spring中TransactionDefinition定義了事務的隔離級別和傳播屬性,隔離級別有spring

  1. ISOLATION_DEFAULT:PlatforTransactionManager默認的隔離級別,也就是數據庫默認的隔離級別,下面四中分別對應數據庫四中隔離級別
  2. ISOLATION_READ_UNCOMMITED:在另一個事務未提交的時候能夠讀取另外一個事務中的數據,會出現髒讀、不可重複讀、幻讀,系統開銷最小,沒有加鎖
  3. ISOLATION_READ_COMMITED:在另一個事務提交以後才能夠讀取數據,防止了髒讀,會出現不可重複讀、幻讀
  4. ISOLATION_REPEATABLE_READ:防止了髒讀、不可重複讀(在一個事物讀取數據以後,第一個事務提交數據,第一個事務再次讀取數據,發現先後不一致),會出現幻讀,讀不加鎖,增刪改加鎖
  5. ISOLATION_SERIALIZABLE:能夠防止髒讀、不可重複讀、幻讀(第一個事務修改涉及到了數據庫中所有行,第二個事務向表中插入一行,第一個事務會發現表中還有沒有修改的行)

spring事務傳播屬性

傳播屬性:定義了多層事務時候的行爲,spring的TransactionDefinition定義了7種事務傳播行爲數據庫

  1. PROPAGETION_REQUIRED:若是已經有事務,則使用當前事務,若是沒有則新開一個事務
  2. PROPAGETION_SUPPORT:若是已經有事務則事務的執行,若是沒有則非事務地執行
  3. PROPAGERION_MANDATORY:若是有事務則支持事務,不然拋出異常
  4. PROPAGETION_REQUIRES_NEW:老是開啓一個新的事務,若是已經有事務,則掛起當前事務
  5. PROPAGETION_NOT_SUPPORT:老是非事務執行,若是有事務則掛起
  6. PROPAGETION_NEVER:老是非事務執行,若是有事務則拋出異常
  7. PEOPAGETION_NESTED:嵌套事務(內層事務不影響外層事務,外層事務失敗會回滾內層事務),若是有事務,則嵌套在當前事務中執行,若是沒有事務則按照PROPAGETION_REQUIRED的方式運行

事務配置解析

spring支持編程式事務,也支持聲明式事務,這裏以聲明式事務的配置爲例。編程

在配置事務管理器的時候配置爲使用cglib生成代理框架

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

上面xml配置的做用spa

# tx命名空間的處理類
org.springframework.transaction.config.TxNamespaceHandler
# annotation-driven標籤的解析類
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser
# 解析標籤annotation-driven的方法
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer#configureAutoProxyCreator

解析該標籤的時候作了如下的事代理

  1. 註冊org.springframework.aop.config.AopConfigUtils#AUTO_PROXY_CREATOR_BEAN_NAME,org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator
  2. 設置InfrastructureAdvisorAutoProxyCreator這個bean對應的屬性,proxyTargetClass,exposeProxy
  3. 註冊bean:AnnotationTransactionAttributeSource
  4. 註冊bean:TransactionInterceptor
  5. 註冊bean:TransactionAttributeSourceAdvisor
  6. 註冊組合component:CompositeComponentDefinition

上面解析標籤的時候注入的這些bean在getBean的時候會起做用,在getBean的時候會判斷是否須要返回包裝後的bean,也就是org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary方法,找到全部的advisor(順便完成初始化),而後判斷找出全部能夠應用到該類的advisor(org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply),而後利用可用的advisor建立proxy(org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy),這個proxy就是原來類的代理,在請求該類的方法的時候是經過代理進行的,在代理中會判斷是否有事務,是否須要開啓事務code

事務處理過程

Spring 事務處理是基於AOP實現的,爲事務方法所在類生成一個代理類,在調用事務方法的時候實際會調用代理類的代理方法,這裏就是component

org.springframework.transaction.interceptor.TransactionInterceptor#invoke

spring事務

在看spring事務處理流程以前,咱們先回顧下直接使用jdbc編程的時候使用事務的流程xml

  1. 拿到數據庫鏈接
  2. 設置數據庫鏈接爲非自動提交
  3. 執行事務操做
  4. 提交事務

spring事務處理的流程也基本類似,只是作了一些封裝

  1. 拿到數據庫鏈接,須要判斷當前事務的傳播級別,有些傳播級別須要新的數據庫鏈接開啓新的事務
  2. 設置數據庫鏈接爲非自動提交
  3. 執行事務操做
  4. 執行事務提交前的一些回調方法,好比:beforeCommit
  5. 提交事務,判斷是否有異常,是須要回滾仍是提交
  6. 執行事務提交後的一個方法,好比:afterCommit

總結

spring事務在屏蔽了一些繁瑣邏輯的同時,也提供了比較好的擴展性,好比支持自定義數據源,自定義事務管理器,並且支持在事務執行先後加入本身的回調用方法。

相關文章
相關標籤/搜索