mur*_*uge 1 sql sql-server message-queue service-broker
我正在研究sql服务器服务代理作为我们应用程序的消息处理技术。
在我们的方案中,从一个客户端应用程序(WPF)发送的消息需要在服务代理中排队,其他客户端应用程序(android)会接收它们。消息是时间敏感的,接收者需要在消息被发送到队列后的“ X”分钟(例如2分钟)之内接收,如果到那时仍无法接收,则消息必须过期并从接收者中删除。队列。
有没有办法告诉服务代理在“ x”分钟后使消息超时?
编辑:添加了我用来测试此脚本。
CREATE DATABASE ServiceBrokerTest
GO
ALTER DATABASE ServiceBrokerTest SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
GO
/****** Object: MessageType [SampleMsgType] ***/
CREATE MESSAGE TYPE [SampleMsgType] AUTHORIZATION [dbo] VALIDATION = NONE
GO
/****** Object: ServiceContract [MsgContract] ******/
CREATE CONTRACT [MsgContract] AUTHORIZATION [dbo] ([SampleMsgType] SENT BY INITIATOR)
GO
/****** Object: ServiceQueue [dbo].[Queue1] ******/
CREATE QUEUE [dbo].[Queue1] WITH STATUS = ON , RETENTION = OFF , POISON_MESSAGE_HANDLING (STATUS = ON) ON [PRIMARY]
GO
/****** Object: BrokerService [MsgService] ******/
CREATE SERVICE [MsgService] AUTHORIZATION [dbo] ON QUEUE [dbo].[Queue1] ([MsgContract])
GO
/****** Object: StoredProcedure [dbo].[SendMsg] ******/
CREATE PROC [dbo].[SendMsg]
@msg NVARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON
DECLARE @handle UNIQUEIDENTIFIER
BEGIN TRANSACTION
BEGIN dialog @handle
FROM SERVICE [MsgService]
TO SERVICE 'MsgService'
ON CONTRACT [MsgContract]
WITH ENCRYPTION = OFF, LIFETIME = 20
;SEND ON CONVERSATION @handle
MESSAGE TYPE [SampleMsgType] (@msg)
END CONVERSATION @handle
COMMIT TRANSACTION
END
/****** Object: StoredProcedure [dbo].[ReceiveMsg] ******/
CREATE PROC [dbo].[ReceiveMsg]
@msg NVARCHAR(MAX) OUT
AS
BEGIN
SET NOCOUNT ON
DECLARE @handle UNIQUEIDENTIFIER
DECLARE @msgTable TABLE (
handle UNIQUEIDENTIFIER,
msg NVARCHAR(MAX),
msgType VARCHAR(300));
SET @handle = NULL
WAITFOR (
RECEIVE [conversation_handle], message_body, message_type_name
FROM [dbo].[Queue1]
INTO @msgTable
), TIMEOUT 25000
SELECT @handle = handle
FROM @msgTable
WHERE msgType = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
IF @handle is not null
BEGIN
END CONVERSATION @handle
END
SELECT @msg = msg
FROM @msgTable
WHERE msgType = 'SampleMsgType'
END
GO
Run Code Online (Sandbox Code Playgroud)
对话框生存期可以在以下BEGIN DIALOG语句中指定:
BEGIN DIALOG @handle
FROM SERVICE [...]
TO SERVICE '...'
ON CONTRACT [...]
, LIFETIME = <dialog lifetime>;
Run Code Online (Sandbox Code Playgroud)
对话框必须在其生存期内完成(双方结束),否则将出错。因此,您可以启动一个具有2分钟生命周期的对话框,并在其上发送一个或多个消息。目标必须在这2分钟内接收并处理该消息,否则对话框将出错。
您还可以使用对话优先级,并在优先级较高的通道上发送对时间敏感的消息。这将确保Service Broker传输将优先级分配给您的敏感消息,并且客户端应用程序RECEIVE语句会“冒泡”优先级较高的时间敏感消息,并首先接收它们。