SQL SERVER实现先进先出队列
SQL server有自己的队列,通过 service broken来做,2014年了解过该技术,使用过程比较复杂;Windows系统有MSMQ,第三方的还有ActiveMQ,RabbitMQ。他们有的支持存储防丢失,有的是基于内存操作,面对在不是那么大的项目中使用,可以考虑使用SQL server的自身事务的一致性来实现一个队列。
1.0 SQL server中的WITH表达式
这里就是一个简单的CTE表达式;紧接CTE表达式后面,去使用MyCTE。CTE可以视为一个临时表;多个with表达式之间可以使用逗号进行分割,这样可以实现关联查询。
WITH MyCTE AS( SELECT * FROM dbo.KO_B ) SELECT * FROM MyCTE;
直接看下面的,使用delete去删除一条数据,时间开销在于where条件后的ID需要和原表逐行匹配,如果表行数比较多,大表的情况下查找会比较耗时。而使用CTE表达式后,不需要执行循环遍历查找操作了。

2.0 利用数据库事务访问控制实现FIFO
数据表结构,

存储过程设计如下
CREATE PROCEDURE spFIFO AS BEGIN SET NOCOUNT ON; WITH CTE AS( SELECT TOP(1) * FROM dbo.KO_B WITH(ROWLOCK) ORDER BY ID ASC ) DELETE FROM CTE OUTPUT Deleted.ID, Deleted.Numbers; END GO
测试2个进程同时访问此对列,APP1生产数据和消费数据;APP2只消费数据
private void ThreadProc4()
{
while (true)
{
_manualResetEvent.WaitOne();
var bl = new KOBHandle();
var res = bl.Dequeue();
Thread.Sleep(200);
if (res == null) {
this.Dispatcher.Invoke(_handleLogMsg, $"队列空{Environment.NewLine}");
continue;
}
this.Dispatcher.Invoke(_handleLogMsg, $"唯一标识:{res.ID} , 数据域:{res.Numbers}{Environment.NewLine}");
//Thread.Sleep(200);
}
}
从日志分析测试结果,192行数据

APP1取出:98个
APP2取出:94个
浙公网安备 33010602011771号