欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql 隊列 實現(xiàn)并發(fā)讀

 更新時間:2012年04月24日 20:39:01   作者:  
隊列是常用的數(shù)據(jù)結(jié)構(gòu),基本特點就是先入先出,在事務(wù)處理等方面都要用到它,有的時候是帶有優(yōu)先級的隊列。當(dāng)隊列存在并發(fā)訪問的時候,比如多線程情況下,就需要鎖機制來保證隊列中的同一個元素不被多次獲取
一個 MySQL 表可以看作是一個隊列,每一行為一個元素。每次查詢得到滿足某個條件的最前面的一行,并將它從表中刪除或者改變它的狀態(tài),使得下次查詢不會得到它。在沒有并發(fā)訪問的情況下,簡單地用 SELECT 得到一行,再用UPDATE(或者DELETE)語句修改之,就可以實現(xiàn)。
復(fù)制代碼 代碼如下:

SELECT * FROM targets WHERE status='C' LIMIT 1;
UPDATE targets SET status='D' WHERE id='id';

如果有并發(fā)訪問,在SELECT和UPDATE語句之間可能會存在其他地SELECT查詢,導(dǎo)致同一行被取出多次。為了保證在并發(fā)情況下仍然能正常工作,一種思路是使用數(shù)據(jù)庫地鎖來防止,就像在多線程環(huán)境下所做地一樣。總之,要是的查詢和修改為一個原子操作,不被其它的訪問干擾。MySQL 5 支持存儲過程,可以用它來實現(xiàn)。
單條 UPDATE 語句應(yīng)該原子操作的,可以利用這個特性來保證并發(fā)訪問情況下隊列的正常工作。每次取元素時,先用 UPDATE 修改符合條件的第一行,然后再得到該行??上?UPDATE 語句沒有返回值,重新用普通的SELECT的話又很難找到剛被改過的那條記錄。
這里用到一個小技巧:在 UPDATE 時加上 id=LAST_INSERT_ID(id),再用 SELECT LAST_INSERT_ID() 即可得到剛修改的那條記錄的id。還有一個問題,當(dāng)表中不存在符合條件的記錄,導(dǎo)致 UPDATE 失敗時,LAST_INSERT_ID() 會保留原來地值不變,因而不能區(qū)分隊列中是否還有元素。
ROW_COUNT() 返回上一個語句影響的行數(shù),把它作為 SELECT 的一個條件,可以幫助解決這個問題。
最后,支持并發(fā)訪問的完整解決方案為:

復(fù)制代碼 代碼如下:

UPDATE targets SET status='D', id=LAST_INSERT_ID(id) WHERE status='C' LIMIT 1;
SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();

更新:在實現(xiàn)帶優(yōu)先級的隊列時這種方法有問題,帶有 ORDER BY ... 條件的 UPDATE 語句非常慢,例如:

復(fù)制代碼 代碼如下:
UPDATE targets SET status='D' WHERE status='C' ORDER BY schedule ASC LIMIT 1;


而單獨查詢和更新則是很快的:
復(fù)制代碼 代碼如下:

SELECT id FROM targets WHERE status='C' ORDER BY schedule ASC LIMIT 1;
UPDATE targets SET status='D' WHERE id='id';


原來這是MySQL的Bug-12915,一年多以前提出來的,雖然關(guān)閉了,卻只解決了部分問題,尚不支持WHERE,見MySQL 5.0.15 的 Changlog。無奈,上面這種巧妙的方法也沒有實用價值了。
最后采用了一種折衷方案,如下:

復(fù)制代碼 代碼如下:

UPDATE targets, (SELECT id FROM targets WHERE status='C' AND schedule<CURRENT_TIMESTAMP ORDER BY schedule ASC LIMIT 1) tmp SET status='D' WHERE targets.id=LAST_INSERT_ID(tmp.id);
SELECT * FROM targets WHERE ROW_COUNT()>0 and id=LAST_INSERT_ID();

相關(guān)文章

  • MySQL xtrabackup 物理備份原理解析

    MySQL xtrabackup 物理備份原理解析

    xtrabackup 是percona公司開源的MySQL innodb物理備份工具,支持在線熱備(備份時不影響數(shù)據(jù)讀寫),在工具在業(yè)內(nèi)生產(chǎn)上被大量使用,本次使用xtrabackup 備份的日志和數(shù)據(jù)庫general 日志來對備份的流程和原理進行解讀,需要的朋友可以參考下
    2022-12-12
  • MySQL數(shù)據(jù)庫主從復(fù)制原理及作用分析

    MySQL數(shù)據(jù)庫主從復(fù)制原理及作用分析

    這篇文章主要介紹了MySQL數(shù)據(jù)庫主從復(fù)制原理并分析了主從復(fù)制的作用和使用方法,有需要的的朋友可以借鑒參考下,希望可以有所幫助,感謝閱讀
    2021-09-09
  • mysql安裝不上怎么辦 mysql安裝失敗原因和解決方法

    mysql安裝不上怎么辦 mysql安裝失敗原因和解決方法

    在我們裝mysql數(shù)據(jù)庫時,出現(xiàn)安裝失敗是一件非常令人煩惱的事情,接下來小編就給大家?guī)碓谖覀儼惭bmysql數(shù)據(jù)庫失敗的一些解決方法,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 在Linux環(huán)境下mysql的root密碼忘記解決方法(三種)

    在Linux環(huán)境下mysql的root密碼忘記解決方法(三種)

    這篇文章主要介紹了在Linux環(huán)境下mysql的root密碼忘記解決方法,詳細(xì)的介紹了3種解決辦法,具有一定的參考價值,有興趣的可以了解一下。
    2016-12-12
  • MySQL基于索引的壓力測試的實現(xiàn)

    MySQL基于索引的壓力測試的實現(xiàn)

    本文主要介紹了MySQL基于索引的壓力測試的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Navicat Premium15連接云服務(wù)器中的數(shù)據(jù)庫問題及遇到坑

    Navicat Premium15連接云服務(wù)器中的數(shù)據(jù)庫問題及遇到坑

    這篇文章主要介紹了Navicat Premium15連接云服務(wù)器中的數(shù)據(jù)庫問題及遇到坑,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • MYSQL大小寫不敏感導(dǎo)致用戶登錄異常問題

    MYSQL大小寫不敏感導(dǎo)致用戶登錄異常問題

    這篇文章主要介紹了MYSQL大小寫不敏感導(dǎo)致用戶登錄異常問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 深入探索數(shù)據(jù)庫MySQL性能優(yōu)化與復(fù)雜查詢相關(guān)操作

    深入探索數(shù)據(jù)庫MySQL性能優(yōu)化與復(fù)雜查詢相關(guān)操作

    數(shù)據(jù)庫MySQL 是一種開源的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在進行 MySQL 數(shù)據(jù)庫開發(fā)過程中,需要深入了解如何進行性能優(yōu)化和復(fù)雜查詢,以提高系統(tǒng)的效率和可靠性,本文介紹的非常詳細(xì),需要的朋友可以參考一下
    2023-04-04
  • MySQL數(shù)據(jù)類型全解析

    MySQL數(shù)據(jù)類型全解析

    這篇文章主要介紹了MySQL數(shù)據(jù)類型的相關(guān)資料,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下
    2021-01-01
  • MySQL5.6.40在CentOS7 64下安裝過程詳解

    MySQL5.6.40在CentOS7 64下安裝過程詳解

    這篇文章主要介紹了MySQL5.6.40在CentOS7 64下安裝過程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06

最新評論