Using SqlDependency vs. periodic polling of a table (performance impact) - c#

In the beginning of our app's development, we were using SqlDependency quite heavily to cache DB results until the notifications told our app to grab a fresh copy.
During testing, we've noticed that the SQL DB's performance was getting hammered by the SqlDependency notification service. We scaled back the number of tables that we were using SqlDependency and noticed a large gain in performance. So, we thought we were just over using it and we moved on. We are down to only a few tables now.
Later, we discovered that we couldn't scale back the security access level for the username that will establish the dependency. We could have more than one connection string for each DB (one for dependency and one for the rest of the app), but with multiple DBs and DB mirroring, this is a pain (from SQL DB admin point of view and app development).
At this point, we are just thinking about moving away from SqlDependency altogether based on the following logic:
We don't need "instant" notification that the data has changed. If we knew within 1 second, that would be fast enough.
With some slight refactoring, we could get it down to just 1 table and poll that table once a second.
Does anyone see a flaw in this logic?
Would polling one table once a second cause more or less load on the DB than SqlDependency?
Has anyone had similar performance issue with SqlDependency?

I do dare try answer your question. But I am not sure you'll get the answer you was hoping for...
I remember back in the early 90ies when Borland promoted this grand new feature of 'callbacks' in their database Interbase that would give the caller (Delphi) 'notifications' via some very nifty new tech where promises was made that the database could be 'active'.
This was later known as the 'waste of time theory'.
And I guess why this never took of is perhaps that while the concept of DBMS was looking very promising, the database is one of your tiers that you can only scale up and not horizontally.
So programming languages to the rescue. Or rather the idea of Service Oriented Architecture (SOA). Many confuse SOA for 'Webservices' that was indeed an included hype in this new concept.
But if you check out the Fiefdom/Emissary design pattern (or Master/Agent pattern renamed to make it sound more cool and professional), you will find that the major idea is having exclusive control of its resources (read databases) and that all calls are being funneled via one single data adapter.
Obviously such a design does not work at all with triggers nor any callback frameworks.
But I think you should reconsider your entire design. If you funnel all actions and all calls via a single 'DataLayer', perhaps using Entity Framework, and perhaps on top on that a Caching mechanism you would not have to rely on your database to forward messages back up the food chain.
To show how weird things can get when being to 'database-centric', here is an extreme actual live example of how not to send an email, written a long long time ago, by a coder I was not so much impressed with:
Fact 1: Sql Server can send emails.
Fact 2: Asp3 coder does not know if or how this can be done in VbScript.
Asp3: read textbox email-address, send to com+ layer
Com+: take email-address and forward to datalayer
Datalayer: take email-address and forward to a stored procedure
Sproc: take email-address and forward to sql function
function: do weird sub-string things to check that email-adress has # . in it. return true or false.
Sproc: return a recordset with one column and one row containing 1 or 0
Datalayer: return the table as is.
Com+: convert the first column and row with value 1 or 0 to true or false
Asp3: if true, send email-adress with email subject and email text to com+
Com+: sends the exact information to datalayer
Datalayer: calls an stored procedure..
Sproc: calls a sql-function...
function: uses sql server email agent to send the email
If you read this far, my advice is to let sql server manage tables, relations, indexes and transactions. It is very good at that. Anything beyond those tasks, and with that I do include cursors in stored procedures, is better handled via proper code.

Related

Design considerations for monitoring SQL database table changes

I am working on an assignment to monitor and log various "system-level messages” within our multi-tier .NET 4 WPF, WCF, SQL 2008 application. By messages, I mean details about an event that has occurred in our application, e.g. user logs in and out or data is saved. By logging, I mean that we will be inserting messages into a light-weight SQL table from which clients can poll and display the latest messages.
The source of these messages could come from several different components in our application e.g. Windows Services, WCF Host in IIS, and even stored procedures in the Database. Ultimately these components modify SQL tables each in their own way. So rather than attacking each of these components independently, I’m thinking I might be able to simplify things by saying that the messages need to be “triggered” when certain tables in SQL are modified (updated, inserted).
The first thing that comes to mind would be a trigger on each of the tables which monitor changes and insert records into the light-weight message table. I’ve always (99% of the time) been of the mindset that database triggers are bad news (Are database triggers evil?). And I would personally much rather develop and debug C# than a SQL trigger.
So, in the pursuit of alternatives, I’ve come across Using SqlDependency to Monitor Database Changes which discusses using the SqlDependency class to detect changes. A quick proof of concept seems to work; however, after looking at several code samples, it looks like with each change that’s detected, new SqlConnection, SqlCommand, and SqlDependency objects will have to be reinitialized and I will probably need 3 or 4 queries that will need to be monitored.
Are there better options to detecting changes to SQL tables in C#?
Also, trigger bias aside, this seems like round-about way to simply monitor changes in one set of tables just to re-insert data into another table. There will be some other logic that will need to take place that I would rather implement in C#, but should I just write triggers to do this and be done with it?
Thoughts?
I think your bias against triggers in general is unfounded. People look down upon triggers for the same reason they look down on cursors: in many cases, they are misused and abused. But like a lot of things they certainly have their place and, when used correctly, are the right answer.
There are some other native technologies you should look into:
Change Tracking
http://msdn.microsoft.com/en-us/library/cc280462(SQL.100).aspx
Change Data Capture
http://msdn.microsoft.com/en-us/library/bb522489(SQL.100).aspx
SQL Server Audit
http://msdn.microsoft.com/en-us/library/cc280386(SQL.100).aspx
Though I don't know your edition (some of these are Enterprise features). Some 3rd party solutions exist as well (I haven't used any so I'll leave it up to you to search / research).

how to handle db concurrency in client-server application in C#?

I am developing an application in C# WPF which will have Client-Server architecture (Client will do products sales billing). I am novice in this area and I asked this question to start my development process.
Click here to view question.
So, ultimately I have selected MySQl, WCf & WPF. Now I have one silly question. Do i need to handle DB concurrency explicitly in my application (like 3 clients inserting data same time) or MySQl will handle this without any conflict?
To accomplish my project i thought, I will create a service in WCf which will do DB queries from client application. Do you have any suggestion to improve my application performance.
With respect to your question about concurrency, your application should be designed to keep connections to the database open as short as possible. Each action on the database should involve: open connection, act on the database, close the connection rather than: open connection, do a bunch of work that may or may not be related to getting/updating/inserting data and then at "the end" close the connection.
Now, with respect to application concurrency, you end up with two scenarios. In scenario one, which I'll call "last write wins", whatever connection writes to a given row last is the version of the data that gets stored. If Alice then Bob write to the Name column on the same row at the same time, Bob's version will be what is stored. This is by far the simplest but if you might have a lot of people updating the same data, it might be problematic.
An alternative is "first write wins" also called Optimistic Concurrency. In this scenario, the second call checks that the data has not changed since it was last retrieved and if it has, then its transaction is rolled back. What happens next depends on your application. Some systems simply throw an error and require the user to re-enter their information (discarding their original change). This is obviously easier to implement. Some applications tell the user that the data has changed and provide some information about what is different and ask whether they want to overwrite this change. That can be more complicated depending on the architecture of your system.
See Optimistic Concurrency for more.
There are a number of ways to handle concurrency, each with their pro's and con's.
This article gives a good general introduction.
If you wish to share more about your requirements around concurrency:
What do you WANT to happen when
multiple people try to edit the same
data?
How frequently do you expect users to edit the same data?
I would be glad to give more specific advice.
Database servers are pretty good at handling multiple updates.
Use netTcpBinding.

Detached Smart Client Syncing

I am working on an application at the minute that will originally be just installed on a client machine with a lightweight database (may SqlLite).
After a while I want to add a web version of the same piece of software and with this the smart client will then be able to sync with the online version.
Has anyone done anything similar, I am looking to know:
What is the best way of syncing, are there patterns around it?
Are there any frameworks out there to handle syncing?
Is there any gotcha's I should be aware of from the start (maybe security concurrency)?
What would be the best way to architect this?
Thansk in advance...
So, Microsofts Sync Framework will help with this. Introduction
Couple of issues stand right out at the beginning.
If you are going to have the data exisit on the client first, then sync to a server at some point later, you need to think about what happens when a number of clients all sync to the server, esp. around conflict resolution.
There are events that get raised on the server side to idetify when a conflict occurs, but you need to decide who wins. (one on server, one from incoming client). Depending on wht you choose to do here, the second sync is likely to modify the client data.
Think carefully about what to sync. If its a contacvts database, is it good enough to have just the client name and telephone number sync, or do you need to whole contact history as well?
Think in terms of syncing a table, using rows where the key is all the same value. Even if this is a constructed table with triggers etc. This makes the framework sync a much simpler process and less prone to errors (tables needed to be synched in different orders).
If its an invoicing program, maybe an upload only table of orders is needed, with all the assoiciated invoice, history, reporting tables etc being updated on the server, rather than updating them on the client and syncing multiple tables....

Monitoring /Watching database (activity) programmatically

I was wondering how to monitor a database for changes programmatically.
Suppose I want to have a .net application which would run after every 100th or(nth) row insertion or row deletion or updation . how can it be achieved?
I know little about triggers.they can be used to fire executable.
But I heard that it isn't a good practice.
Is there any other way?
2]Do database fire events on table updations? and can they be caught in a program?
3]Can SQL reporting services be used here?
(Also assuming that this application is independent from the actual program which does
database manipulation.)
SQL Server 2005 introduced query
notifications, new functionality that
allows an application to request a
notification from SQL Server when the
results of a query change. Query
notifications allow programmers to
design applications that query the
database only when there is a change
to information that the application
has previously retrieved.
Check out the MSDN link for more clarity
and sample immplementation
A trigger is really going to be your only way unless you aren't concerned about the accuracy of "100th" or "nth".
The answer to 2 and 3 are no.
You can write managed stored procedures (MSDN example) but that doesn't help you here really. In general triggers can be bad practice since they can block the initial caller but sometimes they are the only solution.
I think you need to question your requirement to place this low-level data monitoring in a separate application. Think about where your data changes could originate -
Do you have full understanding of every:
stored proc within your db (now and future) and which ones update this table?
application that may hit your database (now and future)
If not, then watching the changes right down at the data level (ie within the db) is probably the best option, and that probably means triggers...
Read about "Service Broker" at http://msdn.microsoft.com/en-us/library/ms166104(v=SQL.90).aspx

Sometimes Connected CRUD application DAL

I am working on a Sometimes Connected CRUD application that will be primarily used by teams(2-4) of Social Workers and Nurses to track patient information in the form of a plan. The application is a revisualization of a ASP.Net app that was created before my time. There are approx 200 tables across 4 databases. The Web App version relied heavily on SP's but since this version is a winform app that will be pointing to a local db I see no reason to continue with SP's. Also of note, I had planned to use Merge Replication to handle the Sync'ing portion and there seems to be some issues with those two together.
I am trying to understand what approach to use for the DAL. I originally had planned to use LINQ to SQL but I have read tidbits that state it doesn't work in a Sometimes Connected setting. I have therefore been trying to read and experiment with numerous solutions; SubSonic, NHibernate, Entity Framework. This is a relatively simple application and due to a "looming" verion 3 redesign this effort can be borderline "throwaway." The emphasis here is on getting a desktop version up and running ASAP.
What i am asking here is for anyone with any experience using any of these technology's(or one I didn't list) to lend me your hard earned wisdom. What is my best approach, in your opinion, for me to pursue. Any other insights on creating this kind of App? I am really struggling with the DAL portion of this program.
Thank you!
If the stored procedures do what you want them to, I would have to say I'm dubious that you will get benefits by throwing them away and reimplementing them. Moreover, it shouldn't matter if you use stored procedures or LINQ to SQL style data access when it comes time to replicate your data back to the master database, so worrying about which DAL you use seems to be a red herring.
The tricky part about sometimes connected applications is coming up with a good conflict resolution system. My suggestions:
Always use RowGuids as your primary keys to tables. Merge replication works best if you always have new records uniquely keyed.
Realize that merge replication can only do so much: it is great for bringing new data in disparate systems together. It can even figure out one sided updates. It can't magically determine that your new record and my new record are actually the same nor can it really deal with changes on both sides without human intervention or priority rules.
Because of this, you will need "matching" rules to resolve records that are claiming to be new, but actually aren't. Note that this is a fuzzy step: rarely can you rely on a unique key to actually be entered exactly the same on both sides and without error. This means giving weighted matches where many of your indicators are the same or similar.
The user interface for resolving conflicts and matching up "new" records with the original needs to be easy to operate. I use something that looks similar to the classic three way merge that many source control systems use: Record A, Record B, Merged Record. They can default the Merged Record to A or B by clicking a header button, and can select each field by clicking against them as well. Finally, Merged Records fields are open for edit, because sometimes you need to take parts of the address (say) from A and B.
None of this should affect your data access layer in the slightest: this is all either lower level (merge replication, provided by the database itself) or higher level (conflict resolution, provided by your business rules for resolution) than your DAL.
If you can install a db system locally, go for something you feel familiar with. The greatest problem I think will be the syncing and merging part. You must think of several possibilities: Changed something that someone else deleted on the server. Who does decide?
Never used the Sync framework myself, just read an article. But this may give you a solid foundation to built on. But each way you go with data access, the solution to the businesslogic will probably have a much wider impact...
There is a sample app called issueVision Microsoft put out back in 2004.
http://windowsclient.net/downloads/folders/starterkits/entry1268.aspx
Found link on old thread in joelonsoftware.com. http://discuss.joelonsoftware.com/default.asp?joel.3.25830.10
Other ideas...
What about mobile broadband? A couple 3G cellular cards will work tomorrow and your app will need no changes sans large pages/graphics.
Excel spreadsheet used in the field. DTS or SSIS to import data into application. While a "better" solution is created.
Good luck!
If by SP's you mean stored procedures... I'm not sure I understand your reasoning from trying to move away from them. Considering that they're fast, proven, and already written for you (ie. tested).
Surely, if you're making an app that will mimic the original, there are definite merits to keeping as much of the original (working) codebase as possible - the least of which is speed.
I'd try installing a local copy of the db, and then pushing all affected records since the last connected period to the master db when it does get connected.

Categories