国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案

這篇具有很好參考價(jià)值的文章主要介紹了超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 超賣問題(多人秒殺)

1.1 原因

  • 多線程并行運(yùn)行
  • 多行代碼操作共享資源,但不具備原子性

例:
超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案,各類優(yōu)化方案,java,數(shù)據(jù)庫(kù),服務(wù)器

1.2 解決方案

針對(duì)并發(fā)安全問題,最廣為人知的解決方案就是加鎖。
從實(shí)現(xiàn)思想上來說,鎖可以分為兩大類:

  • 悲觀鎖
  • 樂觀鎖

悲觀鎖是一種獨(dú)占和排他的鎖機(jī)制,保守地認(rèn)為數(shù)據(jù)會(huì)被其他事務(wù)修改,所以在整個(gè)數(shù)據(jù)處理過程中將數(shù)據(jù)處于鎖定狀態(tài)。

樂觀鎖是一種較為樂觀的并發(fā)控制方法,假設(shè)多用戶并發(fā)的不會(huì)產(chǎn)生安全問題,因此無需獨(dú)占和鎖定資源。但在更新數(shù)據(jù)前,會(huì)先檢查是否有其他線程修改了該數(shù)據(jù),如果有,則認(rèn)為可能有風(fēng)險(xiǎn),會(huì)放棄修改操作。

悲觀鎖、樂觀鎖是對(duì)并發(fā)安全問題的處理態(tài)度不同:

  • 悲觀鎖認(rèn)為安全問題一定會(huì)發(fā)生,所以直接獨(dú)占資源。結(jié)果就是多個(gè)線程會(huì)串行執(zhí)行被保護(hù)的代碼。
    • 優(yōu)點(diǎn):安全性非常高
    • 缺點(diǎn):性能較差
  • 樂觀鎖則認(rèn)為安全問題不一定發(fā)生,所以不獨(dú)占資源。結(jié)果就是允許多線程并行執(zhí)行。但如果真的發(fā)生并發(fā)修改怎么辦??樂觀鎖采用CAS(Compare And Set)思想,在更新數(shù)據(jù)前先判斷數(shù)據(jù)與我之前查詢到的是否一致,不一致則證明有其它線程也在更新。為了避免出現(xiàn)安全問題,放棄本次更新或者重新嘗試一次。

樂觀鎖:

  • 優(yōu)點(diǎn):性能好、安全性也好
  • 缺點(diǎn):并發(fā)較高時(shí),可能出現(xiàn)更新成功率較低的問題(并行的N個(gè)線程只會(huì)有1個(gè)成功)

1.3 總結(jié)

超賣這樣的線程安全問題,解決方案有哪些?

  • 悲觀鎖:添加同步鎖,讓線程串行執(zhí)行
    • 優(yōu)點(diǎn):簡(jiǎn)單粗暴
    • 缺點(diǎn):性能一般
  • 樂觀鎖:不加鎖,在更新時(shí)判斷是否有其它線程在修改
    • 優(yōu)點(diǎn):性能好
    • 缺點(diǎn):存在成功率低的問題

2. 鎖失效問題(單人重復(fù)搶)

2.1 原因

使用Synchronized的代碼塊作為鎖時(shí),鎖使用的是方法中的變量時(shí),此時(shí)一般會(huì)通過tostring()方法將變量轉(zhuǎn)為常量,但由于tostring的底層方法中使用的是:
超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案,各類優(yōu)化方案,java,數(shù)據(jù)庫(kù),服務(wù)器
這種new出來的對(duì)象并不相同,從而導(dǎo)致鎖不相同,從而引發(fā)鎖失效的問題。

2.2 解決方案

String類中提供了intern()方法:
超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案,各類優(yōu)化方案,java,數(shù)據(jù)庫(kù),服務(wù)器
從描述中可以看出,只要兩個(gè)字符串equals的結(jié)果為true,那么intern就能保證得到的結(jié)果用 ==判斷也是true,其原理就是獲取字符串字面值對(duì)應(yīng)到常量池中的字符串常量。因此只要兩個(gè)字符串一樣,intern()返回的一定是同一個(gè)對(duì)象。

3. 事務(wù)邊界問題(單人重復(fù)搶)

3.1 原因

由于鎖過早釋放,導(dǎo)致了事務(wù)尚未提交,并發(fā)的線程判斷出現(xiàn)錯(cuò)誤,最終導(dǎo)致并發(fā)安全問題發(fā)生。
這其實(shí)就是事務(wù)邊界和鎖邊界的問題。
超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案,各類優(yōu)化方案,java,數(shù)據(jù)庫(kù),服務(wù)器

3.2 解決方案

解決方案很簡(jiǎn)單,就是調(diào)整邊界:

  • 業(yè)務(wù)開始前,先獲取鎖,再開啟事務(wù)
  • 業(yè)務(wù)結(jié)束后:先提交事務(wù),再釋放鎖

將加鎖的部分抽取為一個(gè)方法,在方法上加@Transactional事務(wù)注解,在調(diào)用的方法中將抽取的方法放在鎖內(nèi)即可解決
超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案,各類優(yōu)化方案,java,數(shù)據(jù)庫(kù),服務(wù)器

3.3 總結(jié)

在事務(wù)和鎖并行存在時(shí),一定要考慮事務(wù)和鎖的邊界問題。由于事務(wù)的隔離級(jí)別問題,可能會(huì)導(dǎo)致不同事務(wù)之間數(shù)據(jù)不可見,往往會(huì)產(chǎn)生一些不可預(yù)期的現(xiàn)象。

4. 事務(wù)失效問題

4.1 原因

雖然事務(wù)邊界問題已經(jīng)解決,但是其解決方案也埋下了新的隱患。

常見的事務(wù)失效原因:

4.1.1 事務(wù)方法非public修飾

由于Spring的事務(wù)是基于AOP的方式結(jié)合動(dòng)態(tài)代理來實(shí)現(xiàn)的。因此事務(wù)方法一定要是public的,這樣才能便于被Spring做事務(wù)的代理和增強(qiáng)。
而且,在Spring內(nèi)部也會(huì)有一個(gè) org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource類,去檢查事務(wù)方法的修飾符:

@Nullable
 protected TransactionAttribute computeTransactionAttribute(
  Method method, @Nullable Class<?> targetClass) {
   // Don't allow non-public methods, as configured.
   if (allowPublicMethodsOnly() && 
  !Modifier.isPublic(method.getModifiers())) {
      return null;
   }

    // ... 略

   return null;
 }

所以,事務(wù)方法一定要被public修飾!

4.1.2 非事務(wù)方法調(diào)用事務(wù)方法

@Service
public class OrderService {
    
    public void createOrder(){
        // ... 準(zhǔn)備訂單數(shù)據(jù)
        
        // 生成訂單并扣減庫(kù)存
        insertOrderAndReduceStock();
    }
    
    @Transactional
    public void insertOrderAndReduceStock(){
        // 生成訂單
        insertOrder();
        // 扣減庫(kù)存
        reduceStock();
    }
}

可以看到,insertOrderAndReduceStock方法是一個(gè)事務(wù)方法,肯定會(huì)被Spring事務(wù)管理。Spring會(huì)給OrderService類生成一個(gè)動(dòng)態(tài)代理對(duì)象,對(duì)insertOrderAndReduceStock方法做增加,實(shí)現(xiàn)事務(wù)效果。

但是現(xiàn)在createOrder方法是一個(gè)非事務(wù)方法,在其中調(diào)用了insertOrderAndReduceStock方法,這個(gè)調(diào)用其實(shí)隱含了一個(gè)this.的前綴。也就是說,這里相當(dāng)于是直接調(diào)用原始的OrderService中的普通方法,而非被Spring代理對(duì)象的代理方法。那事務(wù)肯定就失效了!

4.1.3 事務(wù)方法的異常被捕獲了

示例:

 @Service
 public class OrderService {

    @Transactional
    public void createOrder(){
        // ... 準(zhǔn)備訂單數(shù)據(jù)
        // 生成訂單
        insertOrder();
        // 扣減庫(kù)存
        reduceStock();
    }

    private void reduceStock() {
        try {
            // ...扣庫(kù)存
        } catch (Exception e) {
            // 處理異常
        }
    }

 }

在這段代碼中,reduceStock方法內(nèi)部直接捕獲了Exception類型的異常,也就是說方法執(zhí)行過程中即便出現(xiàn)了異常也不會(huì)向外拋出。
而Spring的事務(wù)管理就是要感知業(yè)務(wù)方法的異常,當(dāng)捕獲到異常后才會(huì)回滾事務(wù)。
現(xiàn)在事務(wù)被捕獲,就會(huì)導(dǎo)致Spring無法感知事務(wù)異常,自然不會(huì)回滾,事務(wù)就失效了。

4.1.4 事務(wù)異常類型不對(duì)

 
@Service
 public class OrderService {

    @Transactional(rollbackFor = RuntimeException.class)
    public void createOrder() throws IOException {
        // ... 準(zhǔn)備訂單數(shù)據(jù)
        
        // 生成訂單
        insertOrder();
        // 扣減庫(kù)存
        reduceStock();

        throw new IOException();
    }
 }

Spring的事務(wù)管理默認(rèn)感知的異常類型是RuntimeException,當(dāng)事務(wù)方法內(nèi)部拋出了一個(gè)IOException時(shí),不會(huì)被Spring捕獲,因此就不會(huì)觸發(fā)事務(wù)回滾,事務(wù)就失效了。

因此,當(dāng)我們的業(yè)務(wù)中會(huì)拋出RuntimeException以外的異常時(shí),應(yīng)該通過@Transactional注解中的rollbackFor屬性來指定異常類型:

@Transactional(rollbackFor = Exception.class)

4.1.5 事務(wù)傳播行為不對(duì)

 
@Service
 public class OrderService {
    @Transactional
    public void createOrder(){
        // 生成訂單
        insertOrder();
        // 扣減庫(kù)存
        reduceStock();
        throw new RuntimeException("業(yè)務(wù)異常");
    }
    @Transactional
    public void insertOrder() {
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void reduceStock() {
    }
 }

在示例代碼中,事務(wù)的入口是createOrder()方法,會(huì)開啟一個(gè)事務(wù),可以成為外部事務(wù)。在createOrder()方法內(nèi)部又調(diào)用了insertOrder()方法和reduceStock()方法。這兩個(gè)都是事務(wù)方法。
不過,reduceStock()方法的事務(wù)傳播行為是REQUIRES_NEW,這會(huì)導(dǎo)致在進(jìn)入reduceStock()方法時(shí)會(huì)創(chuàng)建一個(gè)新的事務(wù),可以成為子事務(wù)。insertOrder()則是默認(rèn),因此會(huì)與createOrder()合并事務(wù)。
因此,當(dāng)createOrder方法最后拋出異常時(shí),只會(huì)導(dǎo)致insertOrder方法回滾,而不會(huì)導(dǎo)致reduceStock方法回滾,因?yàn)閞educeStock是一個(gè)獨(dú)立事務(wù)。
所以,一定要慎用傳播行為,注意外部事務(wù)與內(nèi)部事務(wù)之間的關(guān)系。

4.1.6 沒有被Spring管理

 
//  @Service
 public class OrderService {
    @Transactional
    public void createOrder(){
        // 生成訂單
        insertOrder();
        // 扣減庫(kù)存
        reduceStock();
        throw new RuntimeException("業(yè)務(wù)異常");
    }
    @Transactional
    public void insertOrder() {
    }
    @Transactional
    public void reduceStock() {
    }
 }

這個(gè)示例屬于比較低級(jí)的錯(cuò)誤,OrderService類沒有添加@Service注解,因此就沒有被Spring管理。你在方法上添加的@Transactional注解根本不會(huì)有人幫你動(dòng)態(tài)代理,事務(wù)自然失效。文章來源地址http://www.zghlxwxcb.cn/news/detail-613585.html

到了這里,關(guān)于超賣等高并發(fā)秒殺場(chǎng)景的問題及解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Redis】電商項(xiàng)目秒殺問題之超賣問題與一人一單問題

    【Redis】電商項(xiàng)目秒殺問題之超賣問題與一人一單問題

    目錄 一、超賣問題 1、背景 2、產(chǎn)生原因以及線程安全問題 3、解決 1.悲觀鎖 2.樂觀鎖 4、新的問題 5、解決 二、一人一單 1、背景 2、產(chǎn)生原因以及線程安全問題 3、解決 4、新的問題 5、解決 三、集群下的并發(fā)問題 1、說明 2、解決 在如雙11等購(gòu)物需求劇增的背景下,一個(gè)物品

    2024年02月04日
    瀏覽(20)
  • 互聯(lián)網(wǎng)中的商品超賣問題及其解決方案:Java中Redis結(jié)合UUID的應(yīng)用

    互聯(lián)網(wǎng)中的商品超賣問題及其解決方案:Java中Redis結(jié)合UUID的應(yīng)用

    在設(shè)計(jì)商品下單和庫(kù)存扣減,你一定遇到過這樣的問題,庫(kù)存扣減為0了,可是消費(fèi)者還能下單,并將訂單信息保存到了數(shù)據(jù)庫(kù)里,針對(duì)商品超賣問題,作此篇以解決。 隨著互聯(lián)網(wǎng)商業(yè)的飛速發(fā)展,商品超賣問題逐漸凸顯為電商平臺(tái)面臨的一大挑戰(zhàn)。尤其是在大型促銷活動(dòng)期

    2024年02月04日
    瀏覽(21)
  • 并發(fā)安全問題之超賣問題

    并發(fā)安全問題之超賣問題

    并發(fā)安全問題之超賣問題 樂觀鎖總結(jié): 優(yōu)點(diǎn) :不加鎖性能好。 缺點(diǎn) :同時(shí)請(qǐng)求成功率低(即只要發(fā)現(xiàn)數(shù)據(jù)變了就放棄了)。 樂觀鎖思想的具體體現(xiàn) :一共兩步,第一步,先查詢狀態(tài)。第二步,再更新數(shù)據(jù)時(shí)必須where等于前面的狀態(tài),確保數(shù)據(jù)沒有改變。 第二步集查詢和操

    2024年02月08日
    瀏覽(17)
  • JMeter壓力測(cè)試案例(商品超賣并發(fā)問題)

    JMeter壓力測(cè)試案例(商品超賣并發(fā)問題)

    壓力測(cè)試可以用來驗(yàn)證軟件系統(tǒng)的穩(wěn)定性和可靠性,在壓力下測(cè)試系統(tǒng)的性能和穩(wěn)定性,發(fā)現(xiàn)并解決潛在的問題,確保系統(tǒng)在高負(fù)載情況下不會(huì)崩潰。 壓力測(cè)試可以用來評(píng)估軟件系統(tǒng)的容量和性能,通過模擬高負(fù)載情況下的用戶訪問量和數(shù)據(jù)量,測(cè)試系統(tǒng)的處理能力和響應(yīng)速

    2024年02月05日
    瀏覽(27)
  • 論文-分布式-并發(fā)控制-并發(fā)控制問題的解決方案

    論文-分布式-并發(fā)控制-并發(fā)控制問題的解決方案

    目錄 參考文獻(xiàn) 問題 解法與證明 易讀版本 參考文獻(xiàn) Dijkstra于1965年發(fā)表文章Solution of a Problem in Concurrent Programming Control,引出并發(fā)系統(tǒng)下的互斥(mutual exclusion)問題,自此開辟了分布式計(jì)算領(lǐng)域 Dijkstra在文中給出了基于共享存儲(chǔ)原子性訪問的解決方案只有十多行代碼,但閱讀起來

    2024年02月08日
    瀏覽(34)
  • 深入探討MySQL并發(fā)事務(wù)的問題及解決方案

    深入探討MySQL并發(fā)事務(wù)的問題及解決方案

    人不走空 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? 目錄 ? ????????個(gè)人主頁(yè):人不走空?????? ??系列專欄:算法專題 ?詩(shī)詞歌賦:斯是陋室,惟吾德馨 1. 臟讀(Dirty Read) 2. 不可重復(fù)讀(Non-repeatable Read) 3. 幻讀(Phantom Rea

    2024年03月09日
    瀏覽(38)
  • 高并發(fā)場(chǎng)景下,6種解決SimpleDateFormat類的線程安全問題方法

    摘要: 解決SimpleDateFormat類在高并發(fā)場(chǎng)景下的線程安全問題可以有多種方式,這里,就列舉幾個(gè)常用的方式供參考。 本文分享自華為云社區(qū)《【高并發(fā)】更正SimpleDateFormat類線程不安全問題分析的錯(cuò)誤》,作者: 冰 河 。 解決SimpleDateFormat類在高并發(fā)場(chǎng)景下的線程安全問題可以

    2024年02月11日
    瀏覽(24)
  • redis的緩存穿透,緩存并發(fā),緩存雪崩,緩存問題及解決方案

    redis的緩存穿透,緩存并發(fā),緩存雪崩,緩存問題及解決方案

    緩存穿透 問題原因 解決方案 緩存并發(fā) 緩存雪崩 緩存失效時(shí)間設(shè)置一致導(dǎo)致的。 解決方案: 1)方案一 2)方案二 如何設(shè)計(jì)一個(gè)緩存策略,緩存熱點(diǎn)數(shù)據(jù)?

    2024年02月21日
    瀏覽(27)
  • 秒殺庫(kù)存解決方案

    秒殺庫(kù)存解決方案

    電商系統(tǒng)中秒殺是一種常見的業(yè)務(wù)場(chǎng)景需求,其中核心設(shè)計(jì)之一就是如何扣減庫(kù)存。本篇主要分享一些常見庫(kù)存扣減技術(shù)方案,庫(kù)存扣減設(shè)計(jì)選擇并非一味追求性能更佳,更多的應(yīng)該考慮根據(jù)實(shí)際情況來進(jìn)行架構(gòu)取舍。在商品購(gòu)買的過程中,庫(kù)存的抵扣過程通常包括以下步驟

    2024年02月13日
    瀏覽(15)
  • 【Redis】電商項(xiàng)目秒殺問題之下單接口優(yōu)化:Redis緩存、MQ以及l(fā)ua腳本優(yōu)化高并發(fā)背景下的秒殺下單問題

    【Redis】電商項(xiàng)目秒殺問題之下單接口優(yōu)化:Redis緩存、MQ以及l(fā)ua腳本優(yōu)化高并發(fā)背景下的秒殺下單問題

    目錄 一、優(yōu)化思路 二、緩存庫(kù)存與訂單 1、庫(kù)存緩存的redis數(shù)據(jù)結(jié)構(gòu) 2、訂單信息緩存的redis數(shù)據(jù)結(jié)構(gòu) 三、整體流程 四、lua腳本確保權(quán)限校驗(yàn)操作的原子性 【Redis】電商項(xiàng)目秒殺問題之超賣問題與一人一單問題_1373i的博客-CSDN博客 https://blog.csdn.net/qq_61903414/article/details/1305689

    2024年02月05日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包