mysql數據庫大規模數據讀寫並行時導致的鎖表問題


問題介紹

最近在給學校做的一個項目中,有一個功能涉及到考核分數問題。
我當時一想,這個問題並不是很難,於是就直接采用了這樣的方法:拿着一個表中的數據作為索引,去挨個遍歷相關表中的數據,最后經過算分的過程,直接在算分函數中將算出的分數直接寫入數據庫,這就導致了標題說的問題。

解決過程

這個問題出現的現象是這樣的:我從數據庫中讀取出來的作為索引的數據共有2000多條,使用增強for循環將數據傳入算分的方法中。但是后來發現,算出分數的數據總計也就300多條,本以為是這條作為索引的數據在其他表中沒有相關的數據造成的分數為0,后來發現,即使是在其他表中有數據的,算出的分數依舊是0。
這個問題着實令人費解,本以為是增強for循環的線程安全問題,后來就將增強for循環改成了迭代器,但是這個問題依舊沒有解決。
緊接着,我想了想,開始測試一下這條分數為0的數據是否被讀入了函數當中,於是我在算分的函數中設置了個判斷條件,結果發現,這條數據真的是沒有被讀入函數。
無奈之下,只能是一點點debug,我將傳入的參數改成了數據表中沒有分數的這條數據的,居然發現這條數據能夠被成功計算出分數。
這時候我整個人已經是懵逼的了,我不禁在想,為什么會出現這種情況?單獨將值傳入函數,可以計算出分數值,但所有數據一起讀寫,就會出現這個問題呢?
此時我已經坐在電腦前debug了一個下午,晚飯也沒有吃,本來中午就應該上線的功能,硬是到了晚上依然沒有被解決,確實有點慌了。
無奈之下只能是請教之前負責這個項目的學長,但是學長有課,只能等到八點半。在等待期間,我依舊是在瘋狂的debug,真的是一點頭緒都沒有。
學長來了之后,他在循環的過程中加入了一個計算次數的變量,每次輸出一下,結果發現,程序並沒有執行完成,總是執行到第420次就停了,期間沒有任何錯誤信息,沒有任何其他異常,詭異的很。
不過這個時候我們已經意識到了是mysql數據庫的問題。
就這樣,學長和我們一起一直盯到了兩點,之前已經將分數采用一次讀取幾百條數據的方式成功將分數算出來交給學校科研院處理了。
隨着學長一個激動的叫聲,問題總算是得到了解決!

最終的解決方案

原來,在我設計的方法中,是讀寫同時進行的。
雖然第一次將數據讀到一個集合中了,但是每次循環都會再次從數據庫中讀取大量的數據,數據的條數超過了幾萬條,這還不算,在每次讀取后,計算出分數,會將分數直接寫入數據庫,就這樣,在頻繁的與數據庫進行讀寫操作的時候,mysql不干了,直接將這個表鎖住了。
這也解釋了為什么系統的其他的功能可以使用,偏偏和分數相關的功能都不能用的問題。
於是最終將寫入分數的步驟單獨拿了出來,這樣子,成功的將所有數據的分數都算了出來。
持續了超過十個小時的過程中,終於將問題解決了。

經驗教訓

經過這次慘痛的教訓,使我深刻明白了一個問題,下次再設計方法的時候,一定要將讀寫操作分開進行,否則就會出現十分嚴重的問題。
雖然整個過程困難無比,但還是收獲巨大的,這種感覺真的特別好。
我想以后真的不可能會忘記讀寫分離這件事情了,哈哈!
謝謝幫忙的學長還有同學!

結語

想了解更多的專業知識、前瞻信息、技術文章嗎?那么請我的個人公眾號:進擊的程序狗,一起進步!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM