multiple SqlConnections for one feature: bad idea? - asp.net

I got an asp.net gridview connected to my sql database. When Inserting a new record or updating a record im doing some serverside checks and then either update/insert a record or do nothing. right now i got 2 methods CheckArtistExists and CheckSongExists which are both using a SqlConnection Object e.g.
public bool CheckSongExists(string _title, int _artistId)
{
int cnt = -1;
using (SqlConnection con = new SqlConnection(CS))
{
//check if song already is exists in DB
SqlCommand cmd = new SqlCommand("Select Count(ID) from tblSong WHERE Title = #newTitle AND ArtistId = #newArtistId;", con);
cmd.Parameters.AddWithValue(#"newTitle", _title);
cmd.Parameters.AddWithValue(#"newArtistId", _artistId);
con.Open();
cnt = (int)cmd.ExecuteScalar();
// if cnt ==1 song exists in DB, of cnt == 0 song doesnt exist
if(cnt == 1)
{ return true; }
else
{ return false; }
}
}
So for the Update function in the gridview i need to establish 3 SqlConnections (at max) one to check for the artist(if artist doesnt exist i have to insert a record to tblArtist first)
then a check if the song exists(only if artist exists) and finally if song doesnt exist I have to insert a new record.
I know database connections are valuable resources thats why i put them in a using block. So im not quite sure if its good style to use 3 SqlConnection objects to update/insert. Can you please tell me if my code is ok or if i should rather use another approach for this problem.
thank you

ADO.NET internally manages the underlying Connections to the DBMS in the ADO-NET Connection-Pool:
In practice, most applications use only one or a few different
configurations for connections. This means that during application
execution, many identical connections will be repeatedly opened and
closed. To minimize the cost of opening connections, ADO.NET uses an
optimization technique called connection pooling.
Connection pooling reduces the number of times that new connections
must be opened. The pooler maintains ownership of the physical
connection. It manages connections by keeping alive a set of active
connections for each given connection configuration. Whenever a user
calls Open on a connection, the pooler looks for an available
connection in the pool. If a pooled connection is available, it
returns it to the caller instead of opening a new connection. When the
application calls Close on the connection, the pooler returns it to
the pooled set of active connections instead of closing it. Once the
connection is returned to the pool, it is ready to be reused on the
next Open call.
So obviously there's no reason to avoid creating,opening or closing connections since actually they aren't created, opened and closed at all. This is "only" a flag for the connection pool to know when a connection can be reused or not. But it's a very important flag, because if a connection is "in use"(the connection pool assumes), a new physical connection must be openend to the DBMS what is very expensive.
So you're gaining no performance improvement if you "reuse" connections but the opposite.
Create, open(in case of Connections), use, close and dispose them where you need them(f.e. in a method)
use the using-statement to dispose and close(in case of Connections) implicitely
So yes, it's absolutely fine to use one connection per method since you are not using a physical connection at all if connection-pooling is enabled (default).
Another question is if you could improve your approach. You could create a stored-procedure which checks existence and updates or inserts accordingly.
Solutions for INSERT OR UPDATE on SQL Server

Related

Oracle connection pooling in ASP.net

I have an old intranet website written with vb.net and using Oracle.ManagedDataAccess mostly doing read operations from Oracle database 11g.
My db connection code is as follows.
Public Shared Function MyDBConnection(ByVal command_text As String, ByVal connstring As String, ByVal ParamArray parameters As OracleParameter()) As DataTable
Dim OraCommand As New OracleCommand
Dim tmp As New DataTable
Using ORAconnection = New OracleConnection(ConfigurationManager.ConnectionStrings(connstring).ConnectionString)
OraCommand.CommandText = command_text
If parameters IsNot Nothing AndAlso parameters.Length > 0 Then
For Each p In parameters
OraCommand.Parameters.Add(p.ParameterName, p.OracleDbType, p.Size).Value = p.Value
Next p
End If
OraCommand.Connection = ORAconnection
Try
ORAconnection.Open()
tmp.Load(OraCommand.ExecuteReader())
Catch ex As OracleException
End Try
End Using
Return tmp
End Function
And my oracle connection string is like this
<add name="ConnectionString" connectionString="User Id=userid;Password=userpadd;Data Source=servername:port/port_dp"/>
I was testing if my connections to the database were closing properly but it looks like connections on the database stayed open after being closed on my code. Eventually they close way after my query completed about 2 minutes, 10 minutes or hours later.
Is this connection pooling at work? or if there is something wrong with my code?
After reading about oracle pooling, it looks like the application should be reusing the same opened connection on the DB but in my case it looks like is opening new connections anyway.
So my question is, should I disable pooling on my connection string to make sure all connections open/close and not have connections lingering on the DB?
No, you should not disable connection pooling. In .NET connection pooling is managed by a mechanism outside of your reach, and you should proceed as if it is not there: open and close your connections as you normally would (i.e. at the beginning and end of every set of operations that you wish to enroll in a transaction/every set of ops that defines a good "unit of work" such as running a report, updating a table etc
The action of opening and closing connections in your code simply leases the from/returns them to the pool. .NET will manage the rest regarding maintaining a cache of some open connections to the db
Yes, there's pooling. The number of connection might have to do with the default value of min and max pool size. Also, OracleCommand does have a Dispose method that you are not calling.
Added: I see your empty catch statement, you don't need it when using "Using" (or ever). The Dispose will still be called if there's an exception.

SQLite: SQLITE_BUSY on ATTACHed database and parallel read-only connection to the attached database

let me try to explain the problem in general parlance.
We are using SQLite 3.7.11 by System.Data.SQLite Wrapper for .NetCF in Version 1.0.80.
We have two database files:
master_data.db
inventory.db
We establish a read-only connection to master_data.db to display some information to the user.
Data Source=master_data.db;Version=3;Read Only=true;Journal Mode=OFF;Synchronous=OFF;
We establish a writable connection to inventory.db to update/insert inventory information depending on some information from master_data.db
Data Source=inventory.db;Version=3;Journal Mode=DELETE;Synchronous=OFF;
To allow consistency checks in update/insert statements, we attach the master_data.db to this connection.
ATTACH 'master_data.db' AS md_db
We start a transaction at inventory.db
SQLiteTransaction tx = connection.BeginTransaction();
We update a simple table in inventory.db without interaction of master_data.db.
using (IDbCommand cmd = connection.CreateCommand())
{
cmd.CommandText = #"UPDATE header_info SET count_time = #countTime";
SQLiteParameterparam = new SQLiteParameter("#countTime",
DateTime.Now.ToUniversalTime())
cmd.Parameters.Add(param)
return cmd.ExecuteNonQuery();
}
We commit the changes and it will hang until timeout occurs and SQLITE_BUSY is raised.
tx.Commit();// BAAM! due to SQLITE_BUSY
We do not understand what's wrong here. The established read-only connection to master_data.db cannot lock the whole database. Even if there is a second and writable (the only one) connection due to the ATTACH command - which was executed by the one and only writable inventory.db connection. We are sure ther is no second connection to inventory.db.
[EDIT]
In the case of error no other transaction to master_data.db is open. Even the connection is not in use but open.
[/EDIT]
May this issue, we are also facing, be part of the problem? SQLite: Multiple Connections to one file - the one and only writable is not persisted
Thanks for your help.
Regards,
Schibbl
When you have attached databases, a transaction always covers all those databases.
So when you want to write to a database, you have to ensure that no other connection has any open transaction on the main database or on any of the attached databases.

How to write unit case for remote database connection in asp web application

I am new to unit testing for web applications
I have a function which creates a connection to a remote mysql database and perform some operations on it .
I want to have a test case which tests the connection is closed or not after the operations on database.
for example
fun1()
{
ODBCConnection con = new ODBCConnection(connString);
con.open();
}
in the above function, the connection is not closed?
how do i check this? can any one help?
In .Net, it's generally best to open your connections immediately before you use them. So rather than building (and testing) a function that connects to the database, you build and test a function that returns the correct connectionstring. You also have a reference database for your testing environment, and so you build your data access methods and create their own connection and test them against your reference database, that the right results come back.
Okay, based on your comment I can help you. Since you will be opening and closing the connection in the same function (as you should), you can do this:
public void fun1()
{
using (ODBCConnection con = new ODBCConnection(connString))
{
con.open();
//use the connection here
}
//connection is closed here because of the using block, even if an exception is thrown
}
There is no need to check if the connection closes in the code above. It will be closed in a timely manner by the using block, and that's guaranteed as much as anything can be in software. Just make sure you use that pattern everywhere you use connections.
In unit testing, the "units" to be tested are methods/functions. You test that the function performs as you expect it to, and nothing more. If you want to test specifically if a connection is closed, than the way to do it is to write a function to close the connection, and test that.

asp.net webservice OnUnload?

I'm creating a web service which has a number of methods, all of which make use of a SqlConnection. It seems logical that I would declare a class level connection and initialise it in the web service constructor.
Problem is I cannot find a definitive way to release the connection when the web service call completes, so I have a connection leak. I've tried overriding the Dipose() method but it doesn't get called in a reasonable timeframe (actually not at all in my testing). For good measure I also tried attaching a handler to the Disposed() event but as expected same problem.
Is there nothing similar to Page.OnUnload for web service classes? It seems hard to believe I would have to establish a separate connection in every individual method.
Any suggestions?
It seems logical that I would declare a class level connection and initialise it in the web service constructor.
No, this doesn't seem logical at all. ADO.NET uses a connection pooling so that you don't need to do this. This connection pool is per connection string per application domain.
So you could simply draw a new connection from the pool in each web method and return it to the pool at the end (the using statements will take care of this):
[WebMethod]
public void Foo()
{
// Here you are NOT creating a new connection to the database
// you are just drawing one from the connection pool
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
// Here you are NOT opening a new connection to the database
conn.Open();
cmd.CommandText = "SELECT id FROM foo";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// do something with the results
}
}
} // Here you are NOT closing the connection, you are just returning it to the pool
}
So here's an advice: don't try to manage connections manually by using some class fields, static fields, ... Leave this management to ADO.NET as it does it better.
Remark: The code I've shown usually resides in a data access layer which is called by the web method.

Asp.net ajax update panel sharing a database connection

I have a dropdown box and a literal tag inside an Update Panel. On the selection change event of the dropdown up requery the database and repopulate the literal tag and then call UPdatePanel.Update().
below, is there are way i can avoid having to create a new Oledbconnection each time as this seems slow. Can i reuse and store:
The Datasource
The connection in the page.
if so, how do i keep this state between calls from the GUI to the server? Here is my selection change code below
protected void cboPeople_SelectedIndexChanged(object sender, EventArgs e)
{
string dataSource = ConfigurationSettings.AppSettings["contactsDB"];
var objConn = new OleDbConnection(dataSource);
string id = People[cboPeople.Text];
UpdateLiteral(objConn, id);
}
With .NET is not a good idea to keep your connection alive longer than needs. Good practice would be to put a using statement around it (so it always gets cleaned up):
string dataSource = ConfigurationSettings.AppSettings["contactsDB"];
using(var objConn = new OleDbConnection(dataSource))
{
string id = People[cboPeople.Text];
UpdateLiteral(objConn, id);
}
.NET uses connection pooling, which means that when you close/dispose of the connection it doesn't actually close the connection, rather resets it and add it back to the pool. The next time a connection is needed it is used from the pool. So the overhead is not as much as you think and it is not slow. In actual fact you will find that it will use the same connection as long as only one at a time is needed.
The danger with keeping connections open is that they never get closed, and in high demand situations you run out of connections.
You need to recreate this for each request. You have a a state less server. you never know when or if your client will call back. You do not want to keep an open connection to the database nor could you simply service multiply clients while maintaining one database connection.
To deploy high-performance
applications, you must use connection
pooling. When you use the .NET
Framework Data Provider for OLE DB,
you do not have to enable connection
pooling because the provider manages
this automatically. For more
information about how to use
connection pooling with the .NET
Framework Data Provider for OLE DB,
see OLE DB, ODBC, and Oracle
Connection Pooling (ADO.NET).
From OleDbConnection Class

Resources