Send TCP Message in Update/Insert/Delete Trigger - sql-server

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.

Related

Block all connections to a database db2

I'm working on logs. I want to reproduce a log in which the application fails to connect to the server.
Currently the commands I'm using are
db2 force applications all
This closes all the connections and then one by one I deactivate each database using
db2 deactivate db "database_name"
What happens is that it temporary blocks the connections and after a minute my application is able to create the connection again, due to which I am not able to regenerate the log. Any Ideas how can I do this?
What you are looking for is QUIESCE.
By default users can connect to a database. It becomes active and internal in-memory data structures are initialized. When the last connection closes, the database becomes inactive. Activating a database puts and leaves them initialized and "ready to use".
Quiescing the database puts them into an administrative state. Regular users cannot connect. You can quiesce a single database or the entire instance. See the docs for some options to manage access to quiesced instances. The following forces all users off the current database and keeps them away:
db2 quiesce db immediate
If you want to produce a connection error for an app, there are other options. Have you ever tried to connect to a non-estisting port, Db2 not listening on it? Or revoke connect privilege for that user trying to connect.
There are several testing strategies that can be used, they involve disrupting the network connection between client and server:
Alter the IP routing table on the client to route the DB2 server address to a non-existent subnet
Use the connection via a proxy software that can be turned off, there is a special proxy ToxiProxy, which was designed for the purpose of testing network disruptions
Pull the Ethernet cable from the client machine, observe then plug it back in (I've done this)
This has the advantage of not disabling the DB2 server for other testing in progress.

How to intercept SQL traffic client side

I'd like to log all SQL that a client app is sending to a remote SQL server I have no access to. I'm thinking of some kind of client side proxy that can log and pass through data. It has to run on the same machine as the client app.
Any ideas appreciated.
SQL Server's protocol, TDS ("Tabular Data Stream") is not encrypted by default, so a trivial packet-forwarder could be used to proxy SQL Server connections and intercept commands (and their responses).
The TDS protocol specification is available from Microsoft's website, you could write your own proxy which can intercept commands that way: https://msdn.microsoft.com/en-us/library/dd304523.aspx?f=255&MSPPError=-2147217396
However, this is a large undertaking. You have other simpler options if you don't need to capture every connection:
If you control your application's source-code, then simply modify all database operations to intercept every SqlCommand's CommandText and Parameter values.
You could skip writing a proxy and instead use native packet-capture, you'll need to use WinPCap: https://www.winpcap.org/
You could also use SQL Server's Profiling features to get a log of every command executed: What are the APIs used by SQL Profiler?
What you are looking is called an SQL Profiler.
In specific - you are looking for an API for one.
I have never used an API of a profiler myself - but this one looks promising.
Also - take a look at this question for another sample.
If you want to have an impression of a working profiler client you can take a look at this answer.

SQL Server 2014 - Service Broker: maximum Services

I am using SQL Server 2014 using FireDAC in Delphi XE7 to connect to the database.
We need an Event to automatically open a form if some Data where changed in a special Table. Therefor we found the TFDEventAlerter which we used to create a Queue and Service for each User.
UserEvent.Names.Add('QUEUE=qUserEvent');
UserEvent.Names.Add('SERVICE=s' + Username);
UserEvent.Names.Add('CHANGE1=usr;SELECT ID FROM dbo.MsgBox WHERE Status = 'A');
So we have got one Queue and a lot of Services that are listening to that Queue. In general this Setup ist working fine.
But if a lot of Users (550 in my case) are connecting to the database and adding new Services to the Queue we got the Problem that we are running into bad Performance enforced by ThreadPool_Starvation as each Service is blocking a Worker-Thread from time to time.
So does anybody know why there is a limitation using Services for the Service Broker in SQL Server 2014?
Is there another way to use the TFDEventAlerter with 500 Users without creating 500 Services? It seems to me, that we are not using the TFDEventAlerter as it is used to be.

How can I implement SQL Server event listeners to trigger a Nodejs function?

I am new to nodejs and I would like to figure out how I could have event listeners from SQL Server trigger a Nodejs function on my server.
For instance, I would like my Nodejs server to receive notifications when there is any change (insert/update) for any given table in my database, which would then trigger an update of the UI on the client-side.
I'm not altogether familiar with SQL Server, but I don't think you'll want to be using your DB server to POSTs to a webhook endpoint anyhow.
You're better off handling this functionality in your application code rather than on your database server.
The general idea is that it's your application that's going to be operating on the database anyhow, so you should have your application send out the the updates to your UI. A high-level step-by-step would look like so:
Client sends request to server
Server receives request and updates database
Upon a successful update of the database, your server sends a response to the client
The client receives the response from the server and adjusts the UI accordingly

ADO.NET Data Service API Versioning

We created an ADO.NET Services on top of our EDMX file as the main entry point for our central application. In the near future a lot of distinct applications will show up and consume our REST Service.
So far, so good but there is one thing I'm missing. I don't want to update all my consumers each time a new version of the ADO.NET Data Services is published. How can I achieve such a legacy compliance?
Thank you,
Stéphane.
The data services client and server do not do version negotation at connection time - they do it for every request. Each request or respond includes a version header that indicates what version of client or server is required to service that request. This means that a downlevel client can communicate with an up-level server so long as the server can respond to those requests without doing anything that requires it to up the version number of the response. Features that require the service to use higher version responses are all off by default.
What this means is that as new version of Data Services are published, the client and server will continue to be able to communicate with each other regardless of which version is installed on the client so long as new features have not been enabled on the server that require a higher version client to respond.

Resources