I am in the process of creating a friendlist using ASP.NET/C# and MSSQL 08. Simple datalist that lists the profile image and name of my friends.
Next to the name, I have a label showing current status of my friend. Like for instance, Online, Offile, Away etc.
My question is, how can I change the value of this label, without having a timer that calls the database all the time asking for the current status?
I would like to have the database (sql server 2008) tell me when a change as occured and tell my business logic to update the status label.
Is this possible?
Thanks!
To accomplish what you are looking for.. And this is just how I would do it, is to create a view based on the table with only the items that are needed to accomplish the task.. For instance, UserID | Online_Status.. Then using AJAX, make a call. It would be so small to the user that they would not even notice the bandwidth usage/processing... etc..etc...
This is pretty much exactly what you said you didn't want, but even if you had 1 million users and space them like 3-5 minutes apart.. You should be ok considering it would take milliseconds to perform the check.
Just my two cents..
I don't think you should do it like that. There are techniques to do this using comet but it will consume a lot of resources from your server clearly reducing the number of users that can access your site/app. The problem is that the the server and client needs to have a socket open for the server to be able to push data to the client.
What I would do is to have the client ask if there are any updates, keeping the payload to a minimum. If the server says there is data that changed the client makes another request to get that data.
You could use the SqlDependency class to get notified when the result of a database query changes.
There is an excellent article on MSDN explaining the SqlDependency class.
To use the SqlDependency class in the context of ASP.Net consider the strategy explained in the following video of MIX 2011.
Hope, this helps.
I believe this is what for the SqlCacheDependency is designed for. If you are using SQL Server 2005 or higher*, it implements a push-notification model from SQL Server to your application to notify you of when a change occurs in your dataset. So each time the cache is invalidated you can get the latest data, but until then it was just will read from your cached dataset and save a trip to the database. The documentation for it is here.
*However*,
As stated in the comments and such, this isn't really what SQL Server is designed for at its core, and I don't know to hand actually how efficient this solution is. If I understand your problem correctly, you would need a cache dependency PER USER which could very well be completely unscalable using this solution. Rather than second-guess what is going to be the most efficient solution, you really should develop, test, measure and find out for yourself. Every situation is going to be different, there is no "right way".
* In Sql Server 2000 and 7 it uses a pull-model.
All options given to this moment are valid ones and that's how most websites do it today; however, the OP is asking for some sort push notification mechanism as opposed to pull, and I think for that kind of thing, websockets are the way to do it.
Related
Folks - apologies for rehashing this topic as I see even here on Stack, there are so many questions on the topic already.
But I find myself in an interesting place and I'm hoping you can help.
High level Question: can SQL SERVER have the leeway to decide that a view should be wrapped in a ISOLATION LEVEL SNAPSHOT?
I know that sounds like a crazy question but I'm trying to exhaust all avenues per an issue I'm encountering.
I'm working with an application that runs 35 queries to retrieve data from another database via Link Server. The queries are simple selects against one table respectively. All DB operations are carried out against SQL SERVER, and retrieval code is ADO.NET/c#, etc.
34 of the queries work flawlessly - but there's this one bad apple, and for it, I get the transaction isolation level snapshot issue.
I've also tested data retrieval outside of the application and when I implement the below snippet on the "problem" query, I also get the issue:
using (var trans = conn.BeginTransaction(IsolationLevel.Snapshot))
However, when I do NOT implement it on said query, all is well.
I've also tested this against the other queries - with and without "Shapshot" - and my results are predictable... With "Shapshot" in place, no queries process... When not implemented, all queries process...
My results suggest that the application is responsible for changing up the data retrieval strategy.
Per their knowledge base, I found this: Locking is handled by the database level (MS SQL Server/Oracle) and not by "us". Generally, locking is row level but the optimizer may choose something different
Unfortunately I don't have native access to the boiler-plate application code responsible for data retrieval. I suspect that this particular query/table has one or more key words - either in the column or query/table naming - that trigger the application to use an alternate retrieval strategy. Per the developer forums, I've asked of this is the case and I'm awaiting a reply...
Anyway back to their mention of the optimizer may choose something different- their optimizer, or perhaps the database optimizer? Can SQL SERVER be set up to make a "judgement call" ? Is the statement unclear or do I just not enough of SQL SERVER and its capabilities?
I know it seems like a crazy question but I really want to knock out all possible avenues here.
Thank you kindly for suspending your disbelieve and humoring that crazy post :)
Apparently objects with the word "valuation" (perhaps because of the sensitive nature implied) cause the application to build the transaction. Once I changed the view name, the data returned to the client successfully.
So yes the application was/is the issue.
I have a server application and client application that the database is shared within a network, What I want to happen is that when the client application inserted/updated/deleted data from a specific table I want the server to be alerted and run some code on it.
How can I possibly achieve this? Any ideas will be a big help! thanks :-)
Use a trigger for push notifications, or keep lastModified information to check for pull notification.
You probably want the former,
edit You can use sys_exec('program') from https://github.com/mysqludf/lib_mysqludf_sys to call an external program from a trigger. Just use that to call whatever server code you have.
Examples and setup instructions can be found via google. e.g. http://bernardodamele.blogspot.com.au/2009/01/command-execution-with-mysql-udf.html
You didn't say what type of database you were using. If you were using MS SQL Server, I'd suggest having a look at their StreamInsight which lets you write "adapters" that deal with data in real-time as it is saved.
I don't know if you'll be able to access/incorporate that in your existing server application though. But depending on what you're trying to achieve, you might not have to.
I am building a Wiki / Blog similar application, and I have a question about the best way to store the View Count for each of the articles. The requirement is that I only want to store the unique number of users that viewed the article and not the total view count. So far I have come up with 3 different ways to accomplish:
1. SQL Server stored procedure: the problem with this approach is that the data is stored in XML data type and it might be a bit complicated to achieve the requirement using this method. I am leaving this as a last resort.
2. MSMQ: this would work great, since I can process the requests serially. The only problem with this approach is that, I cannot ensure that MSMQ is installed on the host server. This one is out of the question!
3. Using Application.Lock(): I know that using this method I can lock access to the Application object, update some entry in the application, update the database, and then call Application.Unlock(). While this sounds as a functional approach, it still feels like a workaround.
Does anyone has a suggestion on what I should do to achieve the requirement?
MsMQ and Application.Lock are def not the options to consider for something simple you want to do. (Application.Lock() is a def NO GO)
I also see no reason for XML. A stored proc does not rely on XML
Create a table
[page,userip]
on every view of the page
insert into <table>(page,userip) values(#page,#userip)
For the statistics just issue the a query
select count(*) from <table> group by userip having page=#page
This identifies a user on its IP, not completely failsafe as multiple users can come from the same ip.
But why not investigate google Analytics? All the info you need (and more)
Is there any way to have a datagrid listen to the database and automatically update the data if the database data is changed? I use a SQL Server database.
I'd like to use Linq-2-SQL if possible
Because #Slaggg asked: there are fairly straightforward ways of doing this, but they're almost certainly going to involve a lot of coding, it'll impact performance pretty significantly, and my strong suspicion is that it'll be more trouble than it's worth.
That said, for a typical n-tier application, at a very high level you'll need:
(1) A way to notify the middle tier when the data changes. You could use custom-code triggers inside each the table that fire off some sort of notification (perhaps using WCF and CLR stored procedures), or you could use a SqlDependency object. Probably the second would work better.
(2) A way to notify each client connected to that middle tier. Assuming that you're using WCF, you'll need to use one of the duplex bindings that are available, such as Net.TCP or HttpPollingDuplex (for Silverlight). You'll need to make sure this is configured correctly on both the client and the server. You'll also need to manually keep track of which clients might be interested in the update, so that you can know which ones to update, and you'll need to be able to remove them from that list when they go away or timeout. Tomek, from the MS WCF team, has some pretty good examples on his blog that you might want to investigate.
(3) A mechanism to update the local client's model and/or viewmodel and/or UI once you get the notification from the middle tier that something has changed. This is more complicated than you'd think: it's difficult enough to keep your UI in sync with your data model under normal circumstances, but it gets dramatically more complicated when that data model can be changing under you from the other direction as well.
The idea behind these sorts of notifications is straightforward enough: but getting all the details right is likely to keep you debugging way into the night. And the guy who has to support all this two years from now will curse your name.
Hope this helps.
It depends from where you are updating the database:
From the same context (in
Silverlight, are you adding,
deleting, editing on the same page)
From a ChildWindow in your
Silverlight application
From an
external, non-related tool, outside
of your Silverlight application
Suppose I have some application A with a database. Now I want to add another application B, which should keep track of the database changes of application A. Application B should do some calculations, when data has changed. There is no direct communication between both applications. Both can only see the database.
The basic problem is: Some data changes in the database. How can I trigger some C# code doing some work upon these changes?
To give some stimulus for answers, I mention some approaches, which I am currently considering:
Make application B polling for
changes in the tables of interest.
Advantage: Simple approach.
Disadvantage: Lots of traffic,
especially when many tables are
involved.
Introduce triggers, which will fire
on certain events. When they fire
they should write some entry into an
“event table”. Application B only
needs to poll that “event table”.
Advantage: Less traffic.
Disadvantage: Logic is placed into
the database in the form of triggers.
(It’s not a question of the
“evilness” of triggers. It’s a design
question, which makes it a
disadvantage.)
Get rid of the polling approach and
use SqlDependency class to get
notified for changes. Advantage:
(Maybe?) Less traffic than polling
approach. Disadvantage: Not database
independent. (I am aware of
OracleDependency in ODP.NET, but what
about the other databases?)
What approach is more favorable? Maybe I have missed some major (dis)advantage in the mentioned approaches? Maybe there are some other approaches I haven’t think of?
Edit 1: Database independency is a factor for the ... let's call them ... "sales people". I can use SqlDependency or OracleDependency. For DB2 or other databases I can fall back to the polling approach. It's just a question of cost and benefit, which I want to at least to think about so I can discuss it.
I'd go with #1. It's not actually as much traffic as you might think. If your data doesn't change frequently, you can be pessimistic about it and only fetch something that gives you a yay or nay about table changes.
If you design your schema with polling in mind you may not really incur that much of a hit per poll.
If you're only adding records, not changing them, then checking the highest id might be enough on a particular table.
If you're updating them all then you can store a timestamp column and index it, then look for the maximum timestamp.
And you can send an ubber query that polls multiple talbes (efficiently) and returns the list of changed tables.
Nothing in this answer is particularly clever, I'm just trying to show that #1 may not be quite as bad as it at first seems.
I would go with solution #1 (polling), because avoiding dependencies and direct connections between separate apps can help reduce complexity and problems.
I think you have covered the approaches I have thought of, there's no absolute "best" way to do it, what matters are your requirements and priorities.
Personally I like the elegance of the SqlDependency class; and what does database independence matter in the real world for most applications anyway? But if it's a priority for you to have database independence then you can't use that.
Polling is my second favourite because it keeps the database clean from triggers and application logic; it really isn't a bad option anyway because as you say it's simple. If application B can wait a few minutes at a time before "noticing" database changes, it would be a good option.
So my answer is: it depends. :)
Good luck!
Do you really care about database independence?
Would it really be that hard to create a difference mechanism for each database type that all have the same public interface?
I am aware of OracleDependency in ODP.NET, but what about the other databases?
SQL Server has something like that, but I've never used it.
You can make an MySqlDependency class, and implement SqlDependency or SqlDependencyForOracle (pooling)
You can use an SQL trigger inside a SQL CLR Database Project and run your code in that project, see: https://msdn.microsoft.com/en-us/library/938d9dz2.aspx
Or, on trigger inside the SQL CLR Database Project you could make a request from the SQL CLR Database Project to the project you actually want to act on the trigger.