性能調優系列前序文章索引:html
程序員在轉型架構師的過程當中須要創建流程化、結構化、系統化的思惟方式,而性能調優是很是可貴的契機,它既給了咱們壓力,也給了咱們動力,跨越它就是突破本身的過程。程序員
今天老兵哥將介紹經過優化開發框架 Spring 來優化系統性能的方法。數據庫
3. 開發框架 Spring瀏覽器
3.1 事務管理緩存
事務(Transaction),是併發控制的基本單位,是用戶定義的一個操做序列。這些操做要麼都作,要麼都不作,是一個不可分割的工做單位。經過使用事務控制,咱們能夠極大地避免邏輯處理失敗致使的髒數據等問題。事務具備 4 個屬性:原子性、一致性、隔離性、持久性等,這四個屬性一般稱爲 ACID 特性。安全
Spring 事務管理是經過 XML 文件或註解 @Transactional 配置的,其背後是靜態代理或動態代理等技術。在代理模式下,那些從代理傳遞傳過來的「外部」方法調用會被攔截,但「自我調用」是不會觸發事務的。例如,在目標對象中調用自身其餘方法的方法是不會觸發事務的,即便被調用的方法標記爲 @Transactional。性能優化
一般,咱們不多關注 Spring 事務管理相關的屬性,但這些屬性的取值會影響系統的性能。Spring 事務管理最重要的兩個特性是:傳播級別、隔離級別。傳播級別,定義了事務的控制範圍;隔離級別,定義了事務在數據庫讀寫方面的控制範圍。咱們知道,事務的控制範圍越大,系統的併發性就會越差,性能也就隨之下降。事務的隔離級別越高,系統的併發性也會越差,性能也會隨之降低。若是不瞭解這些屬性的取值規則,咱們就不能選擇最合適的取值,不知不覺中就會浪費許多系統資源,接下來咱們一塊兒來看看這些屬性。網絡
屬性 | 類型 | 描述 |
---|---|---|
propagation | 枚舉型:Propagation | 傳播級別,可選,默認值:PROPAGATION_REQUIRED |
isolation | 枚舉型:Isolation | 隔離級別,可選,默認值:ISOLATION_DEFAULT |
readOnly | 布爾型 | 讀寫型事務、只讀型事務 |
timeout | INT 型,以秒爲單位 | 事務超時閾值 |
rollbackFor | 一組 Class 類,必須是 Throwable 的子類 | 一組異常類,遇到時必須回滾。默認狀況下 Checked Exceptions 不進行回滾,僅 Unchecked Exceptions(即 RuntimeException 的子類)才進行事務回滾。 |
rollbackForClassname | 一組 Class 類的名字,必須是 Throwable 的子類 | 一組異常類名,遇到時必須回滾 |
noRollbackFor | 一組 Class 類,必須是 Throwable 的子類 | 一組異常類,遇到時不須要回滾 |
Spring 事務管理的傳播級別 Propagation 取值有如下幾種: 架構
傳播級別 | 說明 | 備註 |
---|---|---|
PROPAGATION_REQUIRED | 若是上下文中已經存在事務,那麼就加入到事務中執行;若是上下文中不存在事務,則新建事務執行。 | 這個級別一般能知足處理大多數的業務場景。 |
PROPAGATION_SUPPORTS | 若是上下文中已經存在事務,則支持加入到事務中執行;若是上下文中不存在事務,則使用非事務的方式執行。 | 這個一般是用來處理那些並不是原子性的非核心業務邏輯操做,應用場景較少。 |
PROPAGATION_MANDATORY | 該級別的事務要求上下文中必需要存在事務,不然就會拋出異常。這是避免上下文調用代碼遺漏添加事務控制的保證手段。 | 例如某段代碼不能被單獨調用執行,可是一旦被調用就必需要有事務包含,這種狀況下就可使用這個傳播級別。 |
PROPAGATION_REQUIRES_NEW | 每次都會新建一個事務,而且同時將上下文中的事務掛起,執行當前新建事務完成之後,上下文事務恢復再執行。 | 問題1:若是某個子事務發生回滾,父事務是否回滾?答案是不會,由於子事務是新建事務,父事務已經被掛起,二者不會受到影響。問題2:若是父事務發生回滾,子事務是否回滾?答案是不會,一樣的理由。可是能夠手動控制,一旦子事務回滾,父事務也回滾。 |
PROPAGATION_NOT_SUPPORTED | 若是上下文中已經存在事務,則掛起事務,執行當前邏輯,結束後恢復上下文的事務。 | 這個級別能夠幫助你儘量地縮小事務範圍。一個事務範圍越大,它存在的風險也就越多,例如某段代碼是循環 1000 次的非核心業務邏輯操做,此類代碼若是包在事務中,勢必致使事務太大,很容易出現些難以考慮周全的異常狀況,此時這個級別就派上用場了。 |
PROPAGATION_NEVER | 該級別要求上下文中不能存在事務,一旦有事務,就拋出runtime異常,強制中止執行。 | 無 |
傳播級別 PROPAGATION_REQUIRED 會爲每個被應用到的方法建立一個邏輯事務做用域。每個邏輯事務做用域均可以自主地決定回滾條件,當這樣的邏輯事務做用域被外部邏輯事務做用域所包含時,它們在邏輯上是獨立的,但在實現層面它們會被映射到相同的物理事務上。併發
傳播級別 PROPAGATION_REQUIRES_NEW 爲每個相關的事務做用域使用了一個徹底獨立的事務。在這種狀況下,物理事務也將是不一樣的。所以,外部事務能夠不受內部事務回滾狀態的影響獨立提交或者回滾。
Spring 事務管理的隔離級別 Isolation 取值有如下幾種:
隔離級別 | 說明 |
---|---|
Serializable | 最嚴格的級別,事務串行執行,資源消耗最大。 |
Repeatable Read | 保證了一個事務不會修改已經由另外一個事務讀取但未提交(或回滾)的數據,避免了「髒讀取」和「不可重複讀取」的狀況,但會帶來了更多的性能損耗。 |
Read Committed | 大多數主流數據庫的默認事務等級,保證了一個事務不會讀到另外一個並行事務已修改但未提交的數據,避免了「髒讀取」,該級別適用於大多數系統。 |
Read Uncommitted | 保證了讀取過程當中不會讀取到非法數據。 |
上述說明中涉及的幾個專業術語:
隔離級別與反作用 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
Serializable | 不會 | 不會 | 不會 |
Repeatable Read | 不會 | 不會 | 會 |
Read Committed | 不會 | 會 | 會 |
Read Uncommitted | 會 | 會 | 會 |
從上面這張映射表中,咱們知道最安全的是 Serializable,可是伴隨而來的是高昂的性能開銷。各類傳播級別、隔離級別自己沒有好壞,關鍵是根據業務需求選擇最合適的取值,避免無效的性能損耗。另外,Spring 事務管理還有兩個經常使用屬性,它們的取值也會影響性能:
3.2 二級緩存
緩存做爲提升應用系統性能的一種有效途徑,在事務管理配置不當的狀況下,將很難發揮應有的效用。所以,在作緩存處理或者其餘處理,要考慮事務管理對性能的影響。
關注「 IT老兵哥 」,賦能程序人生!堅持原創不易,請小夥伴們不吝點個「 贊 」哦!推薦軟技能文章,請點擊連接:程序員,怎樣打造我的影響力?
近期熱評系列《 程序員必須懂的架構師入門課 》: