Hallo zusammen,
ich habe Probleme mit meinem Service Broker, der sich aus mir unbekannten Gründen, hin und wieder deaktiviert. Folgende Informationen finde ich im Log:
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the Transaction
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1
Hier mal meine Prozeduren, offenbar mache ich das error handling falsch. Weiß jemand, wie ich das verbessern kann?
CREATE PROCEDURE [dbo].[Start_Queue]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @tableMessages TABLE
(
nachricht_typ sysname
, nachricht xml
, handle uniqueidentifier
, queuing_order BIGINT
);
DECLARE cursorMessages CURSOR FORWARD_ONLY READ_ONLY FOR SELECT nachricht_typ, nachricht, handle FROM @tableMessages ORDER BY queuing_order;
DECLARE @conversation_handle UNIQUEIDENTIFIER;
DECLARE @nachricht XML;
DECLARE @nachricht_typ sysname;
BEGIN TRY
WHILE (1=1)
BEGIN
BEGIN TRANSACTION UndoReceive;
WAITFOR
(
RECEIVE
message_type_name
, message_body
, conversation_handle
, queuing_order
FROM Async_Start_Queue
INTO @tableMessages
), TIMEOUT 1000;
IF (@@ROWCOUNT = 0)
BEGIN
IF @@TRANCOUNT > 0 -- transaction is committable
BEGIN
COMMIT TRANSACTION;
END
BREAK;
END
OPEN cursorMessages;
WHILE (1=1)
BEGIN
FETCH NEXT FROM cursorMessages INTO @nachricht_typ, @nachricht, @conversation_handle;
IF (@@FETCH_STATUS != 0)
BREAK;
IF @nachricht_typ = N'AsyncRequest'
BEGIN
DECLARE @uid uniqueidentifier = NEWID();
INSERT INTO dbo.ServiceBroker ([uid], start, nachricht) VALUES (@uid, sysdatetime(), @nachricht);
EXEC [dbo].[proc_test];
IF @@ERROR <> 0
BEGIN
ROLLBACK TRANSACTION UndoReceive;
-- Kommunikation beenden
END CONVERSATION @conversation_handle WITH ERROR = 127 DESCRIPTION = 'Unable to process message.';
END;
-- Antwort senden
SET @nachricht = CAST(REPLACE(REPLACE(CAST(@nachricht AS NVARCHAR(max)), '<AsyncRequest>', '<AsyncResponse uid="' + CONVERT(varchar(255), @uid) + '">'), '</AsyncRequest>', '</AsyncResponse>') AS XML);
SEND ON CONVERSATION @conversation_handle
MESSAGE TYPE [AsyncAntwort] (@nachricht);
END
ELSE IF (@nachricht_typ = 'http://schemas.microsoft.com/SQL/ServiceBroker/Error' OR @nachricht_typ = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
BEGIN
END CONVERSATION @conversation_handle;
END;
END
CLOSE cursorMessages;
DELETE FROM @tableMessages;
IF @@TRANCOUNT > 0 -- transaction is committable
BEGIN
COMMIT TRANSACTION;
END
END
END TRY
BEGIN CATCH
INSERT INTO dbo.ServiceBrokerErrorLog (nachricht) VALUES (ERROR_MESSAGE());
IF @@TRANCOUNT > 0 -- transaction is committable
BEGIN
COMMIT TRANSACTION;
END
END CATCH
DEALLOCATE cursorMessages;
END
GO
CREATE PROCEDURE dbo.End_Queue
AS
BEGIN
SET NOCOUNT ON;
DECLARE @tableMessages TABLE
(
nachricht_typ sysname
, nachricht xml
, handle uniqueidentifier
, queuing_order BIGINT
);
DECLARE cursorMessages CURSOR FORWARD_ONLY READ_ONLY FOR SELECT nachricht_typ, nachricht, handle FROM @tableMessages ORDER BY queuing_order;
DECLARE @conversation_handle UNIQUEIDENTIFIER;
DECLARE @nachricht XML;
DECLARE @nachricht_typ sysname;
BEGIN TRY
WHILE (1=1)
BEGIN
BEGIN TRANSACTION;
WAITFOR
(
RECEIVE
message_type_name
, message_body
, conversation_handle
, queuing_order
FROM Async_End_Queue
INTO @tableMessages
), TIMEOUT 1000;
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION;
-- Kommunikation beenden
END CONVERSATION @conversation_handle;
BREAK;
END
OPEN cursorMessages;
WHILE (1=1)
BEGIN
FETCH NEXT FROM cursorMessages INTO @nachricht_typ, @nachricht, @conversation_handle;
IF (@@FETCH_STATUS != 0)
BREAK;
IF @nachricht_typ = N'AsyncResponse'
BEGIN
DECLARE @uid uniqueidentifier = @nachricht.value('(AsyncResponse/@uid)[1]', 'NVARCHAR(MAX)');
-- Beendigung der Kommunikation protokollieren
UPDATE dbo.ServiceBroker SET ende = sysdatetime() WHERE [uid] = @uid;
-- Kommunikation beenden
END CONVERSATION @conversation_handle;
END
ELSE IF (@nachricht_typ = 'http://schemas.microsoft.com/SQL/ServiceBroker/Error' OR @nachricht_typ = 'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog')
BEGIN
END CONVERSATION @conversation_handle;
END;
END
CLOSE cursorMessages;
DELETE FROM @tableMessages;
IF @@TRANCOUNT > 0 -- transaction is committable
BEGIN
COMMIT TRANSACTION;
END
END
END TRY
BEGIN CATCH
INSERT INTO dbo.ServiceBrokerErrorLog (nachricht) VALUES (ERROR_MESSAGE());
IF @@TRANCOUNT > 0 -- transaction is committable
BEGIN
COMMIT TRANSACTION;
END
END CATCH
END
GO
Ich habe die Prozeduren auf das wesentliche gekürzt und hoffe dadurch keine anderen Fehler eingebaut zu haben.
Viele Grüße
webbie