Synchronized鎖在Spring事務管理下?
先簡單提示下,關于synchronized關鍵字,一定要慎用,非常影響性能。
首先說明下,synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有以下幾種:
1. 修飾一個代碼塊,被修飾的代碼塊稱為同步語句塊,其作用的范圍是大括號{}括起來的代碼,作用的對象是調用這個代碼塊的對象;
2. 修飾一個方法,被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的對象是調用這個方法的對象;
3. 修改一個靜態的方法,其作用的范圍是整個靜態方法,作用的對象是這個類的所有對象;
4. 修改一個類,其作用的范圍是synchronized后面括號括起來的部分,作用主的對象是這個類的所有對象
我們再簡單的說下spring的事務相關
Spring在不同的事務管理API之上定義了一個抽象層。而應用程序開發人員不必了解底層的事務管理API,就可以使用Spring的事務管理機制。
Spring既支持https://www.52fb.cn式事務管理(也稱編碼式事務),也支持聲明式的事務管理
https://www.52fb.cn式事務管理:將事務管理代碼嵌入到業務方法中來控制事務的提交和回滾,在https://www.52fb.cn式事務中,必須在每個業務操作中包含額外的事務管理代碼
聲明式事務管理:大多數情況下比https://www.52fb.cn式事務管理更好用。它將事務管理代碼從業務方法中分離出來,以聲明的方式來實現事務管理。事務管理作為一種橫切關注點,可以通過AOP方法模塊化。Spring通過Spring AOP框架支持聲明式事務管理。
Spring并不直接管理事務,而是提供了多種事務管理器,它們將事務管理的職責委托給JTA或其他持久化機制所提供的平臺相關的事務實現。每個事務管理器都會充當某一特定平臺的事務實現的門面,這使得用戶在Spring中使用事務時,幾乎不用關注實際的事務實現是什么。
spring的事務的具體配置方法這里就不贅述了。
在Spring中,聲明式事務是通過事務屬性來定義的,事務屬性描述了事務策略如何應用到方法上。事務屬性包含了5個方面,盡管Spring提供了多種聲明式事務的機制,但是所有的方式都依賴這五個參數來控制如何管理事務策略。聲明式事務通過傳播行為,隔離級別,只讀提示,事務超時及回滾規則來進行定義。
隔離級別定義了一個事務可能受其他并發事務影響的程度。在典型的應用程序中,多個事務并發運行,經常會操作相同的數據來完成各自的任務。并發,雖然是必須的,可是會導致下面的問題。① 臟讀(Dirty reads):臟讀發生在一個事務讀取了另一個事務改寫但尚未提的數據時。如果改寫在稍后被回滾了,那么第一個事務獲取的數據就是無效的。
② 不可重復讀(Nonrepeatable read):不可重復讀發生在一個事務執行相同的查詢兩次或兩次以上,但是每次都得到不同的數據時。這通常是因為另一個并發事務在兩次查詢期間更新了數據
③ 幻讀(Phantom read):幻讀與不可重復讀類似。它發生在一個事務(T1)讀取了幾行數據,接著另一個并發事務(T2)插入了一些數據時。在隨后的查詢中,第一個事務(T1)就會發現多了一些原本不存在的記錄
Spring事務的底層是Spring AOP,而Spring AOP的底層是動態代理技術
簡單來說就是在調用方法前開啟事務,調用方法后提交事務。
在多線程環境下,就可能會出現:方法執行完了(synchronized代碼塊執行完了),事務還沒提交,別的線程可以進入被synchronized修飾的方法,再讀取的時候,讀到的是還沒提交事務的數據,這個數據不是最新的,所以就出現了這個問題。
從上面來看,問題就是兩者同時使用時,加鎖沒有包括整個事務。所以解決方法就是將synchronized的鎖加到整個spring事務上,就不會出現線程安全的問題了。
最后,我會一直在頭條分享我的學習筆記,關注,點贊和轉發就是對我最大的支持。