用spring的事務做了個簡單的高并發搶紅包練習,mysql5.7,rc隔離級別。
事務流程:查詢紅包還剩多少沒搶->有剩下的就插入一條搶紅包記錄并更新剩余紅包數。涉及兩個表,一個紅包表,一個搶紅包記錄表。紅包表就一條記錄,20萬的紅包分成2萬份。
/*紅包表的記錄,主鍵id用AutoIncrease自動生成*/
insert into concurrenttest.red_packet(user_id , amount , send_date , total , unit_amount , stock , note)
values(3 , 200000.00 , now() , 20000 , 10.00 , 20000 , "2w個10塊錢的小紅包,一共二十萬");
/*搶包記錄表省略,有個搶包時間方便統計總共用時*/
然后用javascript寫了個3萬次的回圈發異步請求搶紅包。
問題在于,我用兩條sql陳述句:不加for-update(沒有任何鎖控制)和加for-update分別測驗,看的教材(16年出版,當時mysql5.7已出)說加for-update鎖之后雖然不會出現并發問題,但耗時幾乎比之前(30多秒)多了一倍(50多秒)。但我實際運行的時候反而是加了for-update(8分10秒)要比不加鎖(10分30秒)快一點點,運行幾次都是這樣,想請教這是為什么?
uj5u.com熱心網友回復:
加for update執行的是當前讀,可以直接讀到結果。不加鎖的話是事務中的一致性讀,如果在開啟事務和讀資料之間有其他執行緒對資料的并發操作,會導致需要執行undo log,所以會出現時間更長的情況。uj5u.com熱心網友回復:
原來如此,我覺著這樣就都能解釋得通了:
他快是因為機子性能好,執行事務快,undo-log就小;這樣掛起執行緒的開銷比undo-log開銷大得多;我性能比較差,導致一起執行的事務很多undo-log特別大,所以用當前讀避開undo-log反而要快一點點。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/35015.html
標籤:MySQL
上一篇:處理儲存在hive中的資料
下一篇:大佬求解
