sql server 2008 r2 - está - Tutorial de SQL Server 2008 Service Broker: no se puede recibir el mensaje(excepción en transmission_status)
ejemplo service broker sql server (2)
Estoy aprendiendo a usar el Service Broker de SQL Server 2008 R2. Al seguir el tutorial Completar una conversación en una sola base de datos . Siguiendo la Lección 1 , he creado con éxito los tipos de mensajes, el contrato, las colas y los servicios. Siguiendo la Lección 2 , probablemente he enviado el mensaje. Sin embargo, al intentar recibir el mensaje, obtengo el NULL para ReceivedRequestMsg
lugar del contenido enviado.
Al mirar la sys.transmission_queue
, el estado de transmission_status
para el mensaje dice:
Se produjo una excepción al poner en cola un mensaje en la cola de destino. Error: 15517, Estado: 1. No se puede ejecutar como el principal de la base de datos porque el principal "dbo" no existe, este tipo de principal no se puede suplantar o no tiene permiso.
He instalado SQL Server utilizando el inicio de sesión de Windows como Mycomp/Petr
. Estoy usando ese inicio de sesión también para las lecciones.
¿Puedes adivinar cuál es el problema? ¿Qué debo comprobar y / o configurar para que funcione?
Editado el 16/07/2012: Para ayudar a reproducir el problema, esto es lo que hice. ¿Puedes reproducir el error si sigues los siguientes pasos?
En primer lugar, estoy usando Windows 7 Enterprise SP1 y Microsoft SQL Server 2008 R2, Developer Edition, 64 bits (ver. 10.50.2500.0, Directorio raíz ubicado en C: / Archivos de programa / Microsoft SQL Server / MSSQL10_50.SQL_PRIKRYL05 / MSSQL) .
Siguiendo el consejo del tutorial, descargué la base de datos de ejemplo AdventureWorks2008R2_Data.mdf y la copié en C: / Archivos de programa / Microsoft SQL Server / MSSQL10_50.SQL_PRIKRYL05 / MSSQL / DATA / AdventureWorks2008R2_Data.mdf
El SQL Server Management Studio se tuvo que iniciar "Como administrador" para poder adjuntar los datos más adelante. Entonces conecté el servidor SQL.
Haga clic con el botón derecho en Bases de datos, menú contextual Adjuntar ..., botón Agregar ..., apuntado a AdventureWorks2008R2_Data.mdf + OK. Luego seleccionó el AdventureWorks2008R2_Log.ldf de la siguiente cuadrícula (reportado como No encontrado) y presionó el botón Eliminar ... Después de presionar OK, se adjuntó la base de datos y se creó automáticamente AdventureWorks2008R2_log.LDF.
Las siguientes consultas se usaron para ver "Service Broker habilitado / deshabilitado", y para habilitar (el Service Broker se habilitó con éxito para la base de datos):
USE master;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
ALTER DATABASE AdventureWorks2008R2
SET ENABLE_BROKER
WITH ROLLBACK IMMEDIATE;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
- Luego, siguiendo el tutorial, se ejecutaron las siguientes consultas para crear los tipos de mensajes, el contrato, las colas y los servicios:
USE AdventureWorks2008R2;
GO
CREATE MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
[//AWDB/1DBSample/ReplyMessage]
VALIDATION = WELL_FORMED_XML;
GO
CREATE CONTRACT [//AWDB/1DBSample/SampleContract]
([//AWDB/1DBSample/RequestMessage]
SENT BY INITIATOR,
[//AWDB/1DBSample/ReplyMessage]
SENT BY TARGET
);
GO
CREATE QUEUE TargetQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/TargetService]
ON QUEUE TargetQueue1DB
([//AWDB/1DBSample/SampleContract]);
GO
CREATE QUEUE InitiatorQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/InitiatorService]
ON QUEUE InitiatorQueue1DB;
GO
Hasta ahora tan bueno.
- Luego, las siguientes consultas se usan para mirar las colas (ahora están vacías cuando se usan):
USE AdventureWorks2008R2;
GO
SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
- El problema se manifiesta cuando se envía el mensaje:
BEGIN TRANSACTION;
BEGIN DIALOG @InitDlgHandle
FROM SERVICE
[//AWDB/1DBSample/InitiatorService]
TO SERVICE
N''//AWDB/1DBSample/TargetService''
ON CONTRACT
[//AWDB/1DBSample/SampleContract]
WITH
ENCRYPTION = OFF;
SELECT @RequestMsg =
N''<RequestMsg>Message for Target service.</RequestMsg>'';
SEND ON CONVERSATION @InitDlgHandle
MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
(@RequestMsg);
SELECT @RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION;
GO
Al mirar las colas, las colas de Initiator...
y Target...
están vacías, y el mensaje enviado se puede encontrar en sys.transmission_queue
con el error mencionado anteriormente informado a través del transmission_status
.
Deberá otorgar la recepción en su cola de destino para su inicio de sesión. ¡Y debería funcionar!
USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp/Petr];
GO
Y también debe otorgar el envío para su usuario, el permiso en Target Service debería ser suficiente, pero habilite ambos servicios para el futuro.
USE AdventureWorks2008R2 ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/InitiatorService]
TO [Mycomp/Petr] ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/TargetService]
TO [Mycomp/Petr] ;
GO
alter authorization on database::[<your_SSB_DB>] to [sa];
La infraestructura EXECUTE AS requiere que dbo
a un inicio de sesión válido. Service Broker utiliza la infraestructura EXECUTE AS para entregar los mensajes. Un escenario típico que se encuentra con este problema es una computadora portátil corporativa cuando se trabaja desde casa. Usted inicia sesión en la computadora portátil utilizando credenciales almacenadas en caché, e inicia sesión en el SQL utilizando las mismas credenciales almacenadas en caché de Windows. Emite una CREATE DATABASE
y el dbo
se asigna a su cuenta de dominio corporativo. Sin embargo, la infraestructura EXECUTE AS no puede usar las cuentas en caché de Windows, ya que requiere conectividad directa con Active Directory. La parte enloquecedora es que las cosas funcionan bien al día siguiente en la oficina (su computadora portátil está nuevamente en la red corporativa y puede acceder a AD ...). Te vas a casa por la noche, continúas con la Lección 3 ... y de repente ya no funciona. Haz que todo parezca frágil y poco confiable. Es solo el hecho de que se necesita conectividad AD ...
Otra escena que conduce al mismo problema es causada por el hecho de que las bases de datos vuelven a unir el SID de su creador (el inicio de sesión de Windows que emite la CREATE DATABASE
) cuando se restaura o se adjunta. Si usó una cuenta local PC1/Fred
cuando creó la base de datos y luego copió / adjuntó la base de datos a PC2, la cuenta no es válida en PC2 (por supuesto, tiene el alcance de PC1). Nuevamente, no se ve afectado mucho, pero EJECUTE COMO, y esto hace que Service Broker dé el error que ve.
Y el último ejemplo es cuando un usuario crea la base de datos que luego abandona la empresa y se elimina la cuenta de AD. Parece venganza por su parte, pero es inocente. El DB de producción simplemente deja de funcionar, simplemente porque es su SID que el dbo
también asigna. Divertido...
Simplemente cambiando el dbo
para sa
inicio de sesión, arregla todo esto, y todas las partes móviles que dependen de él (y SSB es probablemente la mayor dependencia) comienzan a funcionar.