激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - mysql 隊列 實現并發讀

mysql 隊列 實現并發讀

2019-12-02 15:00MYSQL教程網 Mysql

隊列是常用的數據結構,基本特點就是先入先出,在事務處理等方面都要用到它,有的時候是帶有優先級的隊列。當隊列存在并發訪問的時候,比如多線程情況下,就需要鎖機制來保證隊列中的同一個元素不被多次獲取

一個 MySQL 表可以看作是一個隊列,每一行為一個元素。每次查詢得到滿足某個條件的最前面的一行,并將它從表中刪除或者改變它的狀態,使得下次查詢不會得到它。在沒有并發訪問的情況下,簡單地用 SELECT 得到一行,再用UPDATE(或者DELETE)語句修改之,就可以實現。 

復制代碼代碼如下:


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


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

復制代碼代碼如下:


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(); 


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

復制代碼代碼如下:

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



而單獨查詢和更新則是很快的: 

復制代碼代碼如下:


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



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

復制代碼代碼如下:


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(); 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 老司机免费福利午夜入口ae58 | 久久综合入口 | 国产精品视频一区二区三区综合 | 国产成人精品二区 | 一级毛片在线观看视频 | 久久露脸国语精品国产91 | 久久精品欧美电影 | 欧美亚洲国产一区二区三区 | 国产三级国产精品国产普男人 | 亚洲射情 | 免费看一级视频 | 久久精品a一级国产免视看成人 | 日本一区二区三区高清不卡 | 中文字幕亚洲情99在线 | 国产一及毛片 | 国产日产精品久久久久快鸭 | 亚洲国产女同久久 | 国产1区2区3区在线观看 | 欧美a∨一区二区三区久久黄 | 国产一区二区三区手机在线 | 国产一区免费视频 | 免费国产在线视频 | 亚洲一区二区三区在线 | 久久精品日产第一区二区三区 | 日本在线不卡一区二区 | 日本视频免费 | 97中文| 欧美日韩综合视频 | 精品亚洲一区二区三区 | 一本色道久久99精品综合蜜臀 | 国产一国产精品一级毛片 | 1024亚洲天堂 | 九色p | 日日爱夜夜操 | 午夜亚洲视频 | av成人在线免费观看 | 久久精品日产高清版的功能介绍 | 久久精品美乳 | 91久久久久久久久久久久久久 | 日本精品一区二区 | 日韩在线播放第一页 |