最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java @Transactional與synchronized使用的問題

 更新時間:2023年01月30日 11:57:02   作者:YXXYX  
這篇文章主要介紹了Java @Transactional與synchronized使用的問題,了解內(nèi)部原理是為了幫助我們做擴展,同時也是驗證了一個人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的

引言

@Transactional是spring通過aop讓我們輕松實現(xiàn)事務(wù)控制的一個注解;而synchronized是實現(xiàn)同步的java關(guān)鍵字;但是它們兩個不能一起使用,一起使用會出現(xiàn)

synchronized失效的問題,這里簡單記錄一下這個問題;

發(fā)現(xiàn)問題

我在impl中實現(xiàn)一個功能邏輯時,為了保證冪等性,在方法中使用synchronized保證同一個用戶短時間內(nèi)多次請求只能串行執(zhí)行,因為數(shù)據(jù)變動涉及多張表,所以我又加了一個@Transactional注解,偽代碼如下:

@Transactional
public void demo() {
    ...一些操作...
    synchronized(lock) {
        ...數(shù)據(jù)庫讀寫操作...
    }
}

然后測試時就發(fā)現(xiàn)synchronized沒有生效,確認(rèn)代碼邏輯沒有問題后,查詢了資料發(fā)現(xiàn)了問題;

問題原因

這里不過多解釋@Transactional注解底層,感興趣可以自行查閱資料;

主要原因就是@Transactional注解通過aop實現(xiàn)事務(wù)管理,當(dāng)標(biāo)注該注解的方法執(zhí)行完成后才提交事務(wù),而synchronized代碼塊又是在一個事務(wù)內(nèi),就會出現(xiàn)第一個線程釋放鎖后但是事務(wù)還沒提交,第二個線程就進(jìn)入同步代碼塊獲取到未提交的數(shù)據(jù)庫數(shù)據(jù);

大致如圖:

解決問題

大致思路

解決方法很簡單,既然問題出在事務(wù)未提交,那么只要把對應(yīng)事務(wù)操作的代碼單獨抽取出來,封裝成一個單獨的方法,在synchronized中調(diào)用該方法即可;

如圖:

偽代碼為:

public void demo() {
    ...一些操作...
    synchronized(lock) {
        databaseOption(); // 調(diào)用數(shù)據(jù)庫操作方法
    }
}
@Transactional
public void databaseOption() {
    ...數(shù)據(jù)庫讀寫操作...
}

注意:@Transactional注解修飾的方法需要是public權(quán)限;

雖然這樣寫好像解決了事務(wù)未提交的問題,但是這樣寫會存在新的問題;上面這種是這兩種方法都寫在serviceImpl中,但是這樣調(diào)用databaseOption方法就會出現(xiàn)@Transactional事務(wù)不生效的情況;

@Transactional事務(wù)不生效問題

所以在同一個類內(nèi)部調(diào)用@Transactional標(biāo)注的方法事務(wù)也不會開啟,原因是:

@Transactional事務(wù)管理是基于動態(tài)代理對象的代理邏輯實現(xiàn)的,那么如果在類內(nèi)部調(diào)用類內(nèi)部的事務(wù)方法,這個調(diào)用事務(wù)方法的過程并不是通過代理對象來調(diào)用的,而是直接通過this對象來調(diào)用方法,繞過的代理對象,肯定就是沒有代理邏輯了

依然是@Transactional的底層原理,可以好好研究一下這個注解,面試就有的聊了;

那么解決方法就是:

不要把由@Transactional修飾的databaseOption方法和調(diào)用它的方法放到同一個類中;這里你可以多寫個service放databaseOption方法,但是這樣好像沒有什么意義;我選擇的是把同步代碼塊放到controller中,在controller中調(diào)用serviceImpl中的databaseOption方法;

偽代碼:

controller類

@RestController
public class TestController {
    @Resource 
    private TestService testService;
    @PostMapping("/test")
    public String testInterface() {
            ...一些操作...
        synchronized(lock) {
            testService.databaseOption(); // 調(diào)用數(shù)據(jù)庫操作方法
        }
    }
}

service類

@Service("testService")
public class TestServiceImpl implements TestService {
    @Transactional
    public void databaseOption() {
        ...數(shù)據(jù)庫讀寫操作...
    }
}

這樣就能保證@Transactional事務(wù)生效;但是這樣寫的缺點就是一些邏輯會被拆分到controller中,可讀性會稍差點;

總結(jié)

這就是這兩天我踩的坑,總的來說所有問題的出現(xiàn)都是由于對@Transactional這個注解理解的不透徹,以后還是要了解該注解的實現(xiàn)原理;

到此這篇關(guān)于Java @Transactional與synchronized使用的問題的文章就介紹到這了,更多相關(guān)Java @Transactional與synchronized內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 全面了解JAVA_BaseDAO數(shù)據(jù)處理類

    全面了解JAVA_BaseDAO數(shù)據(jù)處理類

    下面小編就為大家?guī)硪黄媪私釰AVA_BaseDAO數(shù)據(jù)處理類。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • Java通俗易懂系列設(shè)計模式之建造者模式

    Java通俗易懂系列設(shè)計模式之建造者模式

    這篇文章主要介紹了Java通俗易懂系列設(shè)計模式之建造者模式,對設(shè)計模式感興趣的讀者,一定要看一下
    2021-04-04
  • IDEA中Maven的一些常用操作指南

    IDEA中Maven的一些常用操作指南

    intellij idea是一款很流行好用的集成開發(fā)環(huán)境軟件,maven是使用很廣泛的構(gòu)建工具,java開發(fā)者日常少不了與這兩種工具打交道,下面這篇文章主要給大家介紹了關(guān)于IDEA中Maven的一些常用操作指南,需要的朋友可以參考下
    2024-06-06
  • Java 實現(xiàn)跨平臺的操作方式

    Java 實現(xiàn)跨平臺的操作方式

    這篇文章主要介紹了Java 實現(xiàn)跨平臺的操作方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • springboot整合httpClient代碼實例

    springboot整合httpClient代碼實例

    這篇文章主要介紹了springboot整合httpClient代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • spring cloud zuul 與 sentinel的結(jié)合使用操作

    spring cloud zuul 與 sentinel的結(jié)合使用操作

    這篇文章主要介紹了spring cloud zuul 與 sentinel 的結(jié)合使用操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 詳解Java數(shù)組的定義和聲明方法

    詳解Java數(shù)組的定義和聲明方法

    在Java開發(fā)中,數(shù)組是最常用的數(shù)據(jù)結(jié)構(gòu)之一,因此,深入了解Java數(shù)組的定義和聲明是非常必要的,本文將詳細(xì)介紹Java數(shù)組的定義和聲明方法,以及其在實際開發(fā)中的應(yīng)用場景、優(yōu)缺點等方面,需要的朋友可以參考下
    2023-11-11
  • spring boot基于注解的聲明式事務(wù)配置詳解

    spring boot基于注解的聲明式事務(wù)配置詳解

    這篇文章主要介紹了spring boot基于注解的聲明式事務(wù)配置詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Springboot通過請求頭獲取當(dāng)前用戶信息方法詳細(xì)示范

    Springboot通過請求頭獲取當(dāng)前用戶信息方法詳細(xì)示范

    這篇文章主要介紹了Springboot通過請求頭獲取當(dāng)前用戶信息的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-11-11
  • springboot使用線程池(ThreadPoolTaskExecutor)示例

    springboot使用線程池(ThreadPoolTaskExecutor)示例

    大家好,本篇文章主要講的是springboot使用線程池(ThreadPoolTaskExecutor)示例,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12

最新評論

永宁县| 叶城县| 连平县| 罗源县| 昌宁县| 佛学| 新闻| 嘉义市| 高阳县| 台湾省| 琼海市| 宝应县| 定兴县| 巴马| 哈巴河县| 广平县| 康保县| 大丰市| 宜君县| 泰和县| 郸城县| 苗栗市| 宜春市| 泰兴市| 兴山县| 香港 | 潍坊市| 琼海市| 盐亭县| 肃南| 祁门县| 新化县| 清远市| 永州市| 林芝县| 静海县| 盱眙县| 大港区| 隆昌县| 遂川县| 承德县|