問一個mysql並發問題?

來源:互聯網
上載者:User
商務邏輯是這樣的:

統計某一文章每一天的獲贊次數:
tb(id,time,num)
id:文章ID
time:2016-1-31

id,time是複合主鍵

商務程序:

sql_1:select * from tb where id=$id and time=$tif (sql_1)    sql_2:updata from tb set num = num + 1 where id=$id and time=$telse    sql_2_:INSERT INTO tb (id,time,num) values ($id,$t,1)

就是這樣的很簡單邏輯,本來沒有什麼問題,可是最近老是出錯,原因是因為插入重複的複合主鍵,我才知道這樣設計有並發的問題(兩個進程同時判斷通過,就會導致sql_2_執行兩次而出錯);

網上有很多講這樣的知識的,樂觀鎖,悲觀鎖等,但是都是將一些理論知識,一遇到實際問題,就沒人理你了,書本上也基本是理論知識,沒有實際問題的解決方案,我沒有經驗,不知道怎麼解決這個問題,不想用樂觀鎖,需要要建一個version欄位覺得不爽,程式多個地方用到時還不好控制。

意識到這個問題之後,我發現我之前所有的代碼其實都會有這個問題,我相信上面這個邏輯是個非常基本的邏輯,我沒想到會有這樣的問題,好恐怖;

如果需要用到事務,我就把表全改為innodb的;

希望高人指點,就我上面的例子說實際的解決辦法,不要找一些理論知識我看了。

謝謝大家了。

回複內容:

商務邏輯是這樣的:

統計某一文章每一天的獲贊次數:
tb(id,time,num)
id:文章ID
time:2016-1-31

id,time是複合主鍵

商務程序:

sql_1:select * from tb where id=$id and time=$tif (sql_1)    sql_2:updata from tb set num = num + 1 where id=$id and time=$telse    sql_2_:INSERT INTO tb (id,time,num) values ($id,$t,1)

就是這樣的很簡單邏輯,本來沒有什麼問題,可是最近老是出錯,原因是因為插入重複的複合主鍵,我才知道這樣設計有並發的問題(兩個進程同時判斷通過,就會導致sql_2_執行兩次而出錯);

網上有很多講這樣的知識的,樂觀鎖,悲觀鎖等,但是都是將一些理論知識,一遇到實際問題,就沒人理你了,書本上也基本是理論知識,沒有實際問題的解決方案,我沒有經驗,不知道怎麼解決這個問題,不想用樂觀鎖,需要要建一個version欄位覺得不爽,程式多個地方用到時還不好控制。

意識到這個問題之後,我發現我之前所有的代碼其實都會有這個問題,我相信上面這個邏輯是個非常基本的邏輯,我沒想到會有這樣的問題,好恐怖;

如果需要用到事務,我就把表全改為innodb的;

希望高人指點,就我上面的例子說實際的解決辦法,不要找一些理論知識我看了。

謝謝大家了。

實名反對以上答案!!!
mysql:
1.ON DUPLICATE KEY UPDATE語句
ID,time複合主鍵

INSERT INTO tb (id,time,num) values ($id,$t,1) ON DUPLICATE KEY UPDATE num=num+1;

2.悲觀鎖for update

select * from tb where id=$id and time=$t for updateif (sql_1)    sql_2:updata from tb set num = num + 1 where id=$id and time=$telse    sql_2_:INSERT INTO tb (id,time,num) values ($id,$t,1)

沒人回答嗎?

這個可以在轉寄mysql請求,使用memcache獨佔鎖,

最簡單的辦法是將任務全部放到隊列中去,然後使用單線程不斷處理這個任務隊列中的任務,這樣解決了並發問題,但是效率就變低了。

我在用多線程寫檔案的時候也遇到過多線程同時寫檔案的問題,這個時候用線程鎖(Python):

import threadinglock = threading.Lock()with lock:    # done something

使用redis實現分布式鎖,鎖的位置如下
lock
sql_1:select * from tb where id=$id and time=$t
if (sql_1)

sql_2:updata from tb set num = num + 1 where id=$id and time=$t

else

sql_2_:INSERT INTO tb (id,time,num) values ($id,$t,1)

unlock

我說過 我去年看過的一解決辦法,我舉個不切實際(ps:但是我覺得這個解決辦法還是蠻好的,你可以去看一下《redis實戰》這本書)的個例子,你建立100條資料,關聯一篇新的文章,然後如果有更新,隨機的更新1-100的資料 +1 。等到了一個合適的時候,把這100條合并成1條

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.