Asp.net SQL backed sessions - asp.net

If I have sessions backed by SQL Server and run a command sequence like
HttpContext.Current.Session['user']
HttpContext.Current.Session['user']
Will this make 2 requests to the session DB table to fetch the value, or does asp.net do anything special with the Session object to prevent multiple DB hits?

Definitely YES.
I have SQL server session state setup and i ran Profiler on it. And could clearly see optimized DB calls.
If fact there are optimizations for getting multiple session items in one shot.
Like the below code will also result in SINGLE optimized set of calls (Note: Its not a plain single DB call to get session item)
HttpContext.Current.Session['user']
HttpContext.Current.Session['userTwo']
NOTE: Tested in .NET 4
You can implement your own session state provider if you need.
http://msdn.microsoft.com/en-us/library/ms178587.aspx

Related

How to implement synchronized Memcached with database

AFAIK, Memcached does not support synchronization with database (at least SQL Server and Oracle). We are planning to use Memcached (it is free) with our OLTP database.
In some business processes we do some heavy validations which requires lot of data from database, we can not keep static copy of these data as we don't know whether the data has been modified so we fetch the data every time which slows the process down.
One possible solution could be
Write triggers on database to create/update prefixed-postfixed (table-PK1-PK2-PK3-column) files on change of records
Monitor this change of file using FileSystemWatcher and expire the key (table-PK1-PK2-PK3-column) to get updated data
Problem: There would be around 100,000 users using any combination of data for 10 hours. So we will end up having a lot of files e.g. categ1-subcateg5-subcateg-78-data100, categ1-subcateg5-subcateg-78-data250, categ2-subcateg5-subcateg-78-data100, categ1-subcateg5-subcateg-33-data100, etc.
I am expecting 5 million files at least. Now it looks a pathetic solution :(
Other possibilities are
call a web service asynchronously from the trigger passing the key
to be expired
call an exe from trigger without waiting it to finish and then this
exe would expire the key. (I have got some success with this approach on SQL Server using xp_cmdsell to call an exe, calling an exe from oracle's trigger looks a bit difficult)
Still sounds pathetic, isn't it?
Any intelligent suggestions please
It's not clear (to me) if the use of Memcached is mandatory or not. I would personally avoid it and use instead SqlDependency and OracleDependency. The two both allow to pass a db command and get notified when the data that the command would return changes.
If Memcached is mandatory you can still use this two classes to trigger the invalidation.
MS SQL Server has "Change Tracking" features that maybe be of use to you. You enable the database for change tracking and configure which tables you wish to track. SQL Server then creates change records on every update, insert, delete on a table and then lets you query for changes to records that have been made since the last time you checked. This is very useful for syncing changes and is more efficient than using triggers. It's also easier to manage than making your own tracking tables. This has been a feature since SQL Server 2005.
How to: Use SQL Server Change Tracking
Change tracking only captures the primary keys of the tables and let's you query which fields might have been modified. Then you can query the tables join on those keys to get the current data. If you want it to capture the data also you can use Change Capture, but it requires more overhead and at least SQL Server 2008 enterprise edition.
Change Data Capture
I have no experience with Oracle, but i believe it may also have some tracking functionality as well. This article might get you started:
20 Using Oracle Streams to Record Table Changes

Asynchronous processing .NET SQL Server?

After many years of programming, I need to do something asynchronously for the very first time (because it takes several minutes and the web page times out -- don't want the user waiting that long anyway). This action is done by only a few people but could be done a few times per day (for each of them).
From a "Save" click on an ASP.NET web page using LINQ, I'm inserting a record into a SQL Server table. That then triggers an SSIS package to push that record out to several other databases around the country.
So..
How can I (hopefully simply) make this asynchronous so that the user can get on with other things?
Should this be set up on the .NET side or on the SQL side?
Is there a way (minutes later) that the user can know that the process has completed and successfully? Maybe an email? Not sure how else the user can know it finished fine.
I read some threads on this site about it but they were from 2009 so not sure if much different now with Visual Studio 2012/.NET Framework 4.5 (we're still using SQL Server 2008 R2).
It is generally a bad idea to perform long-running tasks in ASP.Net. For one thing, if the application pool is recycled before the task completes, it would be lost.
I would suggest writing the request to a database table, and using a separate Windows Service to do the long-running work. It could update a status column in the database table that could be checked at a later time to see if the task completed or not, and if there was an error.
You could use Service Broker on the SQL side; it'sa SQL Server implementation of Message Queueing.
Good examples here and here
What you do is create a Service Broker service and define some scaffolding (queues, message types, etc).
Then you create a service "Activation" procedure which is basically a stored procedure that consumes messages from queue. This SP would receive for example a message with an ID of a record in a table, and would then go on and do whatever needs to be done to it, perhaps sending an email when it's done, etc.
So from your code-behind, you'd call a simple stored procedure which would insert the user's data into a table, and send a message to the queue with for e.g the ID of the new record, and then immediately return. I suppose you should tell the user upfront that this could take a few minutes and they'll receive an email, etc.
The great thing about Service Broker is message delivery is pretty much guaranteed - even if your SQL Server falls over right after the message is queued, when you bring it back up the activation SP will just kick off again, so it's very robust.

Storing temp data outside of SQL Server for faster access times

I have an SQL Server(SQL Azure) table that is being queried at a high rate, but gets updated only few times a month.
I wonder what options do I have that can cache the result set on the application side so that it will not have to hit SQL Server all the time.
One option is to just [OutputCache] the action methods which return the views. You may even be able to get away with SQL Dependency caching, though not sure if this works with Azure.
Another option is to try implementing a second-level cache for EF.
Another option is to have an entirely different read model. This way, you wouldn't query against the table, but something else that is closer to IIS and/or faster than SQL Azure (like NoSQL or JSON from Azure cache).

SQL connection timeout

We have been facing weird connection timeouts on one of our websites.
Our environment is composed of an IIS 7 web server (running on Windows Server 2008 R2 Standard Edition) and an SQL Server 2008 database server.
When debugging the website functionality that provokes the timeout, we notice that the connection itself takes milliseconds to complete, but the SqlCommand, which invokes a stored procedure on the database, hangs for several minutes during execution, then raises the timeout exception.
On the other hand, when we run the stored procedure directly on the database, it takes only 2 seconds to correctly finish execution.
We already tried the following:
Modified SqlCommand timeout on the website code
Modified execution timeout on the web.config file
Modified sessionState timeout on the web.config file
Modified authorization cookie timeout on the web.config file
Modified the connection timeout on the website properties on IIS
Modified the application pool shutdown time limit on IIS
Checked the application pool idle timeout on IIS
Checked the execution timeout on the SQL Server properties (it's set to 0, unlimited)
Tested the stored procedure directly on the database with other parameters
We appreciate any help.
Nirav
I've had this same issue with a stored procedure that was a search feature for the users. I tried everything, include ARTIHABORT etc. The SP joined many tables, as the users could search on anything. Many of the parameters for the SP were optional, meaning they had a default value of NULL in the SP. Nothing worked.
I "fixed" it by making sure my ADO.NET code only added parameters where the user selected a value. The SP went from many minutes to seconds in execution time. I'm assuming that SQL Server handled the execution plan better when only parameters with actual values were passed to the SP.
Note that this was for SQL Server 2000.
A few years ago I had a similar problem when migrating an app from SQL2000 to SQL2008.
I added OPTION (RECOMPILE) to the end of all the stored procs in the database that was having problems. In my case it had to do with parameters that were very different between calls to the stored proc. Forcing the proc to recompile will force SQL to come up with a new execution plan instead of trying to use a cached version that may be sub-optimal for the new params.
And in case you haven't done it already, check your indexes. Nothing can kill db performance like lack of a badly needed index. Here is a good link (http://sqlfool.com/2009/04/a-look-at-missing-indexes/) on a query that will display missing indexes.
Super-super late suggestion, but might come handy for others: A typical issue I saw and rather applicable to Java is the following:
You have a query which takes a string as a parameter. That string is search criterion on a varchar(N) column in the database. however, you submit the string param in the query as Unicode (nvarchar(N)). This will result in a full-table scan and conversion of every single field values to Unicode for proper comparison, to avoid potential data loss (if SQL Server converted the input param to non-Unicode, it may lose information).
Simple test: run the query twice (for the sake of simplicity, I'm assuming it's an SP):
exec spWhatever 'input'
exec spWhatever N'input'
See how they behave. Also, you may want to take a look at the Recent Expensive Queries section on the Activity Monitor in SSMS and ask for the execution plan, to clarify the situation.
Cheers,
Erik

Number of total select statement for particular web page?

I was wondering what is the easiest way to see total number of database queries from my ASP.Net (.NET 2.0) application.
My application heavily use sql 2005 database because all data are dynamic and everything goes through one connection string in web.config. Connection pooling is enabled there.
So, I am wondering how many select statements are executed for particular page I load in my browser.
I don't care if I can see that information from .net side or from db side as long as I can see only connections to MY database. Not all connections to that db server because I use shared db server and there is a lot of other databases.
The best way to do this is to set up a profiler on your database and then make a single request to your ASP.NET application. The profiler will aggregate any data you wish and you will be able to use that data to determine what queries were sent to SQL Server from your application.
The SQL Server Profiler will list all actions performed on your DB. If you use a different db login name for your project (probably a really good idea if you are not) you can filter so it only shows actions from your login (see Events Selection, Column Filters then Login Name).
Use SQL Profiler. You can configure it to filter by the database you want and to just show select statements.
If you have some sort of database layer in your code, you could modify it to write out a log message every time you run a select statement. Then just load the page once and count the number of log statements. This may or may not work, depending on how your code is structured, but it's an option.
Edit: I misread the question. I thought you had multiple clients connecting to the same database, not the same database server. In that case, a profiler probably is the best choice.
Do you have access to SQL Server Profiler? You can set up traces to monitor this sort of thing by loading a page and looking at the effects in the profiler.
JUst be aware that Profiler can affect performance, so it is best to do this on dev.

Resources