artículos / SQL Service Broker: herramienta para env...

SQL Service Broker: herramienta para envío de mensajes en SQL Server

geosuna 8 minutos de lectura 3 vistas

Explora cómo utilizar SQL Service Broker para orquestar notificaciones en tiempo real hacia sistemas externos desde SQL Server, asegurando control, seguridad y escalabilidad.

SQL Service Broker: herramienta para envío de mensajes en SQL Server

SQL Service Broker: herramienta para envío de mensajes en SQL Server

En escenarios donde es necesario notificar de forma inmediata a sistemas externos cuando ocurre una acción en la base de datos, SQL Service Broker se presenta como una solución robusta y escalable. Esta tecnología permite orquestar mensajes asíncronos desde SQL Server sin bloquear las operaciones internas, garantizando integridad y seguridad.

¿Qué es SQL Service Broker?

SQL Service Broker es un componente de SQL Server que habilita la mensajería y el procesamiento distribuido mediante colas y contratos de servicio para comunicación asíncrona. Es ideal para escenarios donde, por ejemplo, al registrar un nuevo cliente en una tabla, se requiere enviar un mensaje a un sistema externo, como un CRM o servicio de notificaciones.

Ejemplo Práctico: Notificación al insertar un cliente

Tabla de eventos OutboxCustomerEvents

Se utiliza una tabla para almacenar los eventos generados al insertar un nuevo cliente, registrando datos del cliente y el estado de la notificación. Por ejemplo:

de>CREATE TABLE [dbo].[OutboxCustomerEvents](
 [EventId] [int] IDENTITY(1,1) NOT NULL,
 [Membresia] varchar NULL,
 [Nombre] varchar NULL,
 [ApellidoPaterno] varchar NULL,
 [ApellidoMaterno] varchar NULL,
 [Email] varchar NULL,
 [Telefono] varchar NULL,
 [Celular] varchar NULL,
 [Sexo] varchar NULL,
 [FechaNacimiento] [date] NULL,
 [Cliente] varchar NULL,
 [Notificado] [bit] NULL,
 [CorreoVerificado] [bit] NULL,
 [UltimaVerificacion] [datetime] NULL,
 [EstatusUltimaVerificacion] varchar NULL,
 [Estado] varchar NULL,
 [AttemptCount] [int] NULL,
 [LastError] nvarchar NULL,
 [CreatedAt] [datetime] NULL,
 [SentAt] [datetime] NULL,
 [ProcessedBy] varchar NULL,
 [LockedAt] [datetime] NULL,
)

Trigger para enviar mensaje con Service Broker

Al insertarse un cliente en la tabla principal, el trigger inserta un evento en la tabla OutboxCustomerEvents y envía un mensaje a Service Broker para notificación asíncrona:

de>CREATE TRIGGER [dbo].[trg_Customer_AfterInsert]
ON [dbo].[Customer]
AFTER INSERT
AS
BEGIN
 SET NOCOUNT ON;

 DECLARE @ConversationHandle UNIQUEIDENTIFIER
 DECLARE @MessageBody NVARCHAR(MAX)
 DECLARE @EventId INT
 DECLARE @ErrorMessage NVARCHAR(4000)
 DECLARE @Cliente VARCHAR(20)

 BEGIN TRY
 SELECT @Cliente = C.Cliente 
 FROM inserted i 
 INNER JOIN Ecommerce_db.dbo.CTE C ON C.Tarjeta = i.Membresia

 INSERT INTO [dbo].[OutboxCustomerEvents] (
 Membresia, Nombre, ApellidoPaterno, ApellidoMaterno,
 Email, Telefono, Celular, Sexo, FechaNacimiento, Cliente,
 Notificado, CorreoVerificado, UltimaVerificacion, 
 EstatusUltimaVerificacion, Estado, CreatedAt
 )
 SELECT
 i.Membresia, i.Nombre, i.ApellidoPaterno, i.ApellidoMaterno,
 i.Email, i.Telefono, i.Celular, i.Sexo, i.FechaNacimiento, @Cliente,
 i.Notificado, i.CorreoVerificado, i.UltimaVerificacion,
 i.EstatusUltimaVerificacion, 'PENDING', GETDATE()
 FROM inserted i

 SET @EventId = SCOPE_IDENTITY()
 SET @MessageBody = CAST(@EventId AS NVARCHAR(10))

 BEGIN DIALOG CONVERSATION @ConversationHandle
 FROM SERVICE [PatientEventService]
 TO SERVICE 'PatientEventService'
 ON CONTRACT [PatientEventContract]
 WITH ENCRYPTION = OFF;

 SEND ON CONVERSATION @ConversationHandle
 MESSAGE TYPE PatientEventMessage;

 END TRY
 BEGIN CATCH
 SET @ErrorMessage = ERROR_MESSAGE()

 UPDATE [dbo].[OutboxCustomerEvents]
 SET LastError = 'Error en trigger: ' + @ErrorMessage,
 Estado = 'FAILED'
 WHERE EventId = @EventId
 END CATCH
END

Listener en Python para recibir los mensajes

Un ejemplo básico de un listener en Python que se conecta a SQL Server para escuchar mensajes y procesarlos:

de>import pyodbc

conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=server_name;DATABASE=Ecommerce_db;UID=user;PWD=password')
cursor = conn.cursor()

while True:
 cursor.execute('WAITFOR (RECEIVE TOP(1) CONVERT(NVARCHAR(MAX), message_body) AS message FROM dbo.QueueName), TIMEOUT 10000')
 row = cursor.fetchone()
 if row:
 message = row.message
 print(f'Recibido mensaje: {message}')
 # Aquí incluir lógica para enviar mensaje a sistema externo
 # Después de procesamiento, cerrar conversación o actualizar estado
 else:
 print('Esperando mensajes...')

Ventajas de esta implementación

  • Control total de reintentos: Los mensajes quedan registrados y se pueden reintentar en caso de fallos.
  • Acción inmediata sin bloqueo: El trigger sólo detona el envío, el proceso es asíncrono y no afecta la inserción principal.
  • Escalabilidad: Se pueden crear múltiples canales y contratos para diversos tipos de mensajes y sistemas externos.
  • Seguridad: El usuario de Service Broker no requiere permisos elevados, minimizando riesgos.
  • Integridad y trazabilidad: Todo evento y su resultado quedan registrados para auditoría y análisis.

compartir_artículo

LinkedIn Facebook X

artículos_relacionados