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个

 

 

 

 

 

 

posted on 2022-11-18 14:26  益而不损  阅读(512)  评论(0)    收藏  举报