Using SQL Server Service Broker with multiple routes - sql-server

When using the SQL Server Service Broker - if I had a service with two routes configured and I executed the BEGIN DIALOG statement without specifying the desired target broker instance, which of the possible destinations would it pick as the destination for the message?
I realise with BEGIN DIALOG I can explicitly target a specific broker, but this is only optional. What would happen without it? Would the message be sent to both routes?

I can't find the supporting documentation right now, but my memory says that it will choose one of the routes arbitrarily. It was meant as a means of being able to load balance among n databases that provide the same processing capability and you as the sender of the message don't care which of them actually does the processing.

Related

How can i get alarmed if the master's GTID differs from the slave?

The MaxScale distributes the requests to the MariaDB database -> master/slave server on which the database is located.
What i need is a script running as a cron or something similar which verifies the GTID from master and slaves. If the slaves GTID differs from the masters GTID i want to be informed/alarmed via email.
Unfortunately i have no idea if this is possible somehow and how to do it
You can enable gtid_strict_mode to automatically stop the replication if GTIDs from the same domain conflict with what is already in the binlogs. If you are using MaxScale, it will automatically detect this and stop using it.
Note that this will not prevent transactions from other GTID domains from causing problems with your data. This just means you'll have to pay some attention if you're using multi-domain replication.
If you want to be notified of this, you can use the script option in MaxScale to trigger a custom script to be launched whenever the server stops replicating.

Filtering SQL profiler web services entries

Is there a way to filter SQL profiler data to show only data from current user/session?
I tried using the LoginName or SessionLoginName filters, but the problem is that most of the calls are made by the application's web service and I see no indication who called this service.
SQL Server does not have the context of the end client when multiple tiers are involved so there is no trace column you can filter on to identify requests originating from a specific end client session. The easiest method is to trace in an isolated test environment with a single client.
If the web service has an end client session context identifier, the service could specify the client session id as the Application Name in the connection string so that you can filter on a specific client session. However, that should generally be done only in a test environment since a separate connection pool is created for each unique connection string.

Send TCP Message in Update/Insert/Delete Trigger

I am building a support ticket system using Sql Server 2014, ASP.Net MVC 5, angular JS etc.
As part of the design I want a way for my system to know when a ticket has been updated, deleted, or created.
That way if a user has a ticket open and it is changed while they have it open I can design the system to force them to refresh the ticket before they themselves can make changes to it, to prevent User B from overriding User A's changes they haven't seen.
Ideally, I'd like to design a TCP Protocol server as a Windows Service and be able to connect to it and send it data from table triggers in Sql Server.
Then the application front end would use Javascript and WebSockets. So the application would be connected to the socket server as well as sql server. When a user opens a ticket I would send a message that user XXY has Ticket 00X open. When a change happens in sql server it tells the server Ticket 00X changed. Then the Socket server tells clients connected to it that are looking at Ticket 00X that it has changed and the javascript prevents a submit until a fresh is done.
But... Can sql server do this at all? Doesn't appear so.
So I'm wondering if it's posisble to build a plugin for SQL Server to enable support for it like PostgreSQL's Notify feature.
Update:
I've discovered User Defined CLR Functions in SQL Server and have managed to get it working. (C#/.Net Framework) I made a static class with some static methods like,
public static int NotifyTicketUpdate(int ticketID)
{
//...
}
Then I registered it in SQL Server,
USE TLCDB;
CREATE ASSEMBLY MyCompanyName_MyDll
FROM 'd:\pathtodll\mydll.dll'
WITH PERMISSION_SET = SAFE;
CREATE FUNCTION XYZ_Notify_Ticket_Updated(#input int) RETURNS int
AS EXTERNAL NAME MyCompanyName_MyDll.UserDefinedFunctions.NotifyTicketUpdated;
Then to call it in SQL, I just do
select dbo.XYZ_Notify_Ticket_Updated(#ticketIDHere);
And it all works. My Static method in c# sends the TCP/IP message to my socket server, the server then checks to see who is looking at that ticket ID and sends them a Ticket_Updated message. The websocket layer running in client javascript sees it, and locks the ticket for updates/saves.
Or you can use Service Broker for handling asynchronous notifications. Not the simplest thing to learn, but lightweight, scalable and already built-in.
You could use CLR, which requires a bit of setup.
You could create an EXE that you can shell with parameters from an SP.
You could implement some standard concurrency. Optimistic vs Pessimistic
So yes, it's possible.

ODBC - multiple connections from one app to the same data source

I vaguely remember reading somewhere (in MSDN ODBC documentation?) that one application cannot make more than one connection to a single data source. It seemed to me that I need one connection that all the threads of the application will have to share.
I was trying to look this information up, but I can't seem to find it anymore. Does anyone know/remember how this works?
It all might become a problem in our app, since some of its threads will dynamically connect to data sources of their choice. I don't want to see random connection errors if two of them will connect at the same time to one source, so I wanted to double check this info.
Maybe the statement you are referring to in the MSDN documentation, is the one that says only one statement can be active on a single connection. It says:
Multiple Active Statements per Connection
After SQL Server has received a statement, the SQL Server TDS protocol does not allow acceptance of any other statements from that connection until one of the following occurs:
The client application processes the entire result set.
The client sends a statement telling the server it can close the remainder of the result set.
This means that when an ODBC application is using a default result set, SQL Server does not support multiple active statement handles on a connection handle and only one statement can be actively processed at any point in time.
When an ODBC application is using API server cursors, however, the driver can support multiple active statements on a connection. When the rowset for each cursor command has been received back at the client, SQL Server considers the statement to have completed, and it accepts another statement from another statement handle over that connection handle.
Multiple connections are fine. Multiple statements per connection, not so fine.
No, there is no restriction like that in ODBC itself. It is possible that a specific driver might for some reason limit the connections, but I am not aware of any limitations according to the specification.

Get hostname when reading Service Broker Queue (SQL Server 2005)

I am trying to configure auditing on my SQL Server using Service Broker. I did all the configuration needed to capture the DDL Events (queue, routes, endpoints, event notification). It is working properly except that I am not able to get the hostname of the client from where the DDL event originated from.
Using the service broker's activation procedure, I tried reading the value from the message_body, but there's no xml element that contains the hostname. I can see a value for the SPID but am unable to make use of it. Exec'ing sp_who and querying sys.processes against this SPID doesn't return any value. And running sp_who without parameter shows only one process (I think it's the background process used by the service broker). Is it all because the message was sent asynchronously? But why will it cause the activation context to see different data on sys.processes view?
I am aware that there are DDL triggers that can achieve the same goal, but it seems it is tightly coupled to the command that causes it to fire. So if the triggers fails, the command will also fail.
UPDATE: I managed to retrieve the Hostname by using a combination of xp_cmdshell and sqlcmd (command line app). But I also realized that since the message is asynchronous, it is not always reliable (The SPID who issue the DDL command might have been disconnected already before the message is read from the queue).
I'm not exactly sure what you're trying to implement here, but it's expected that activated procedure will only see a subset of rows in DMVs. This has to do with activation context which often impersonates a different user that you use when debugging the procedure. That impersonated user will only see these rows of server-level views and DMVs to which it has permissions. See here and here for more info.

Resources