【发布时间】:2014-05-15 07:19:57
【问题描述】:
我为两个存储过程设置了内部激活。一是插入一条或多条记录,二是更新同一张表中的一条或多条记录。所以,我有两个发起者,两个目标队列。 到目前为止它在开发中运行良好,但我想知道当我们将它移到经常调用这两个存储过程的 prod 时我可能会遇到什么类型的问题。我们已经遇到了由这两个存储过程引起的死锁问题。异步执行是我这个实现的主要目标。
问题:
有没有办法为两个存储过程使用一个目标队列来防止出现死锁?
我可以做些什么来使它更可靠?像一个执行错误不应该停止传入的请求 去排队?
提高可扩展性(每秒执行次数较多)的技巧?
如果出现死锁,我可以设置 RETRY 吗?
这里是插入存储过程的部分代码;
CREATE QUEUE [RecordAddUsersQueue];
CREATE SERVICE [RecordAddUsersService] ON QUEUE [RecordAddUsersQueue];
ALTER QUEUE [AddUsersQueue] WITH ACTIVATION
( STATUS = ON,
MAX_QUEUE_READERS = 1, --or 10?
PROCEDURE_NAME = usp_AddInstanceUsers,
EXECUTE AS OWNER);
CREATE PROCEDURE [dbo].[usp_AddInstanceUsers] @UsersXml xml
AS
BEGIN
DECLARE @Handle uniqueidentifier;
BEGIN DIALOG CONVERSATION @Handle
FROM SERVICE [RecordAddUsersService]
TO SERVICE 'AddUsersService'
ON CONTRACT [AddUsersContract]
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @Handle
MESSAGE TYPE [AddUsersXML] (@UsersXml);
END
GO
CREATE PROCEDURE [dbo].[usp_SB_AddInstanceUsers]
AS
BEGIN
DECLARE @Handle uniqueidentifier;
DECLARE @MessageType sysname;
DECLARE @UsersXML xml;
WHILE (1 = 1)
BEGIN
BEGIN TRANSACTION;
WAITFOR
(RECEIVE TOP (1)
@Handle = conversation_handle,
@MessageType = message_type_name,
@UsersXML = message_body
FROM [AddUsersQueue]), TIMEOUT 5000;
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION;
BREAK;
END
IF (@MessageType = 'ReqAddUsersXML')
BEGIN
--<INSERT>....
DECLARE @ReplyMsg nvarchar(100);
SELECT
@ReplyMsg = N'<ReplyMsg>Message for AddUsers Initiator service.</ReplyMsg>';
SEND ON CONVERSATION @Handle
MESSAGE TYPE [RepAddUsersXML] (@ReplyMsg);
END
ELSE
IF @MessageType = N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog'
BEGIN
END CONVERSATION @Handle;
END
ELSE
IF @MessageType = N'http://schemas.microsoft.com/SQL/ServiceBroker/Error'
BEGIN
END CONVERSATION @Handle;
END
COMMIT TRANSACTION;
END
END
GO
谢谢,
库兹
【问题讨论】:
标签: sql sql-server internal service-broker activation