1. 程式人生 > >MYSQL資料庫模擬佇列實現

MYSQL資料庫模擬佇列實現

1、首先MYSQL資料庫的預設事務隔離級別為:REPEATABLE-READ 可重複讀。


2、如果不是上述隔離級別,請先修改隔離級別為可重複讀,修改方法如下:

mysql> set session transaction isolation level REPEATABLE READ;

 

3、開啟兩個命令列視窗,分別登入mysql,並命名為session1和session2,以模擬兩個消費者消費模擬佇列的資料(已提前儲存好6條佇列資料,不再模擬生產者的行為)。註釋:id為自增主鍵、session用來儲存sessionId,msg是待消費的資料體,status是消費狀態(un_use:未消費,using:消費中,used:已消費)。

 

4、分別在SESSION1和SESSION2中開啟事務,並查詢此時佇列中的資料狀態,可以看到全部為un_use狀態。

mysql> start transaction;

 


5、現在開始消費,session1先消費,假設每次消費2條。

mysql> update user set session=CONNECTION_ID(),status='using' where status='un_use' limit 2;

 

6、假如此時session2併發消費訊息

情況(1)如果session1還沒有commit事務,session2需要等待,一直等到session1提交事務(見情況(2)),或者session2超時回滾或重試。


情況(2)如果session1已經commit事務,則神奇的一幕出現了。

可以看到:session2執行update語句更新資料,更新的是id=1008,1009的兩條訊息!!!(講道理應該更新1006,1007,為什麼會更新1008和1009呢?除非,session2感知到了1006和1007被session1更新過了,但是從select結果上看,session2並沒有感知到1006和1007已變化,這是一個神奇的東西,或許和MVCC有關,請懂的大牛們指教!)

 

7、既然如此,session1和session2都拿到了自己應該處理的訊息,那就可以進行訊息處理了,處理完訊息以後,通過id來更新資料庫狀態就不存在併發問題了。

 


8、通過上面兩session交替執行更新,可以進行併發更新,周而復始。


9、如果執行過程中session中斷,則會造成一部分using狀態的資料變成殭屍資料,此時可以結合定時任務,對using資料進行進行掃描。
https://blog.csdn.net/wbb_1216/article/details/72998040