程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 多線程下不重復讀取SQL Server的數據

多線程下不重復讀取SQL Server的數據

編輯:關於SqlServer

  在進行一些如發送短信、郵件的業務時,我們經常會使用一個表來存儲待發送的數據,由後台多個線程不斷的從表中讀取待發送的數據進行發送,發送完成後再將數據轉移到歷史表中,這樣保證待發送表的數據一般情況下不會太多。如待發送表結構為:

  Create Table SMS(ID int not null identity(1,1),Content varchar(1024),Status int not null,CreateTime datetime);

  Status 取值:0未讀取 1已讀取

  這樣設計的好處是,不會因為後端有時發送過慢導致前端接收發送消息的請求出現問題,如發送短信的業務,有時由於運營商的網關原因發送太慢,這樣前端可以先將用戶的發送請求全部放在待發送表中,由後端進行慢慢發送。

  在後端發送進程一般使用

  Select top 100 * From SMS Where Status=0;這樣的SQL取出未被讀取的數據。

  為了提高後端發送能力,需要部署多個進程同時從待發送表中取出數據進行發送,這樣有時就會造成同一個記錄被多個進程同時取出來,並發送的情況。

  今天查了一下SQL Server 的MSDN,發現可以通過先更新同時通過deleted表(就像是在觸發器中使用一樣)取出的方式,來保證每條記錄只會被讀取一次。

declare @Rowid table(rowid int);
BEGIN
 set rowcount 100; --一次讀取的行數
 --先將要讀取的記錄狀態更新
 update Sms set [status]= 1  output deleted.ID into @Rowid Where [status] = 0;
 --讀取剛更新狀態的記錄
 select  * from Sms where ID in (select Rowid from @Rowid);
END

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved