回覆列表
  • 1 # java技術情報局

    先簡單提示下,關於synchronized關鍵字,一定要慎用,非常影響效能。

    首先說明下,synchronized是Java中的關鍵字,是一種同步鎖。它修飾的物件有以下幾種:

    1. 修飾一個程式碼塊,被修飾的程式碼塊稱為同步語句塊,其作用的範圍是大括號{}括起來的程式碼,作用的物件是呼叫這個程式碼塊的物件;

    2. 修飾一個方法,被修飾的方法稱為同步方法,其作用的範圍是整個方法,作用的物件是呼叫這個方法的物件;

    3. 修改一個靜態的方法,其作用的範圍是整個靜態方法,作用的物件是這個類的所有物件;

    4. 修改一個類,其作用的範圍是synchronized後面括號括起來的部分,作用主的物件是這個類的所有物件

    我們再簡單的說下spring的事務相關

    Spring在不同的事務管理API之上定義了一個抽象層。而應用程式開發人員不必瞭解底層的事務管理API,就可以使用Spring的事務管理機制。

    Spring既支援程式設計式事務管理(也稱編碼式事務),也支援宣告式的事務管理

    程式設計式事務管理:將事務管理程式碼嵌入到業務方法中來控制事務的提交和回滾,在程式設計式事務中,必須在每個業務操作中包含額外的事務管理程式碼

    宣告式事務管理:大多數情況下比程式設計式事務管理更好用。它將事務管理程式碼從業務方法中分離出來,以宣告的方式來實現事務管理。事務管理作為一種橫切關注點,可以透過AOP方法模組化。Spring透過Spring AOP框架支援宣告式事務管理。

    Spring並不直接管理事務,而是提供了多種事務管理器,它們將事務管理的職責委託給JTA或其他持久化機制所提供的平臺相關的事務實現。每個事務管理器都會充當某一特定平臺的事務實現的門面,這使得使用者在Spring中使用事務時,幾乎不用關注實際的事務實現是什麼。

    spring的事務的具體配置方法這裡就不贅述了。

    在Spring中,宣告式事務是透過事務屬性來定義的,事務屬性描述了事務策略如何應用到方法上。事務屬性包含了5個方面,儘管Spring提供了多種宣告式事務的機制,但是所有的方式都依賴這五個引數來控制如何管理事務策略。宣告式事務透過傳播行為,隔離級別,只讀提示,事務超時及回滾規則來進行定義。

    隔離級別定義了一個事務可能受其他併發事務影響的程度。在典型的應用程式中,多個事務併發執行,經常會操作相同的資料來完成各自的任務。併發,雖然是必須的,可是會導致下面的問題。① 髒讀(Dirty reads):髒讀發生在一個事務讀取了另一個事務改寫但尚未提的資料時。如果改寫在稍後被回滾了,那麼第一個事務獲取的資料就是無效的。

    ② 不可重複讀(Nonrepeatable read):不可重複讀發生在一個事務執行相同的查詢兩次或兩次以上,但是每次都得到不同的資料時。這通常是因為另一個併發事務在兩次查詢期間更新了資料

    Spring事務的底層是Spring AOP,而Spring AOP的底層是動態代理技術

    簡單來說就是在呼叫方法前開啟事務,呼叫方法後提交事務。

    在多執行緒環境下,就可能會出現:方法執行完了(synchronized程式碼塊執行完了),事務還沒提交,別的執行緒可以進入被synchronized修飾的方法,再讀取的時候,讀到的是還沒提交事務的資料,這個資料不是最新的,所以就出現了這個問題。

    從上面來看,問題就是兩者同時使用時,加鎖沒有包括整個事務。所以解決方法就是將synchronized的鎖加到整個spring事務上,就不會出現執行緒安全的問題了。

  • 2 # 淺析架構

    Spring AOP的底層技術是動態代理,也就是說會在加鎖的業務方法外開啟事務。所以真正執行有事務的方法的順序是開啟事務,加鎖,執行業務邏輯,釋放鎖,提交事務。這樣看來,事務還沒有提交,鎖已釋放,導致其他執行緒讀到的資料不是最新更新的資料。解決方法是可以在事務方法外面加鎖,這樣就安全了,不過這樣鎖的粒度太粗,也會影響效能。

  • 3 # 演算法金融

    Spring AOP的底層技術是動態代理,也就是說會在加鎖的業務方法外開啟事務。所以真正執行有事務的方法的順序是開啟事務,加鎖,執行業務邏輯,釋放鎖,提交事務。這樣看來,事務還沒有提交,鎖已釋放,導致其他執行緒讀到的資料不是最新更新的資料。解決方法是可以在事務方法外面加鎖,這樣就安全了,不過這樣鎖的粒度太粗,也會影響效能。具體使用什麼方法,還是需要根據業務case by case。

  • 中秋節和大豐收的關聯?
  • 高爾夫嘉旅、別克GL6、科米克、領界怎麼選?人生第一輛車?