Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET, the SqlConnection object, and multi-threading

We have an application which uses an SQL Server 2008 R2 database. Within the application, calls to the database are made using a SqlConnection object.

This SqlConnection object is initialized once, the first time it is accessed, and then re-used throughout the application. The action that we use is the following:

Protected _cn As SqlConnection = Nothing

...

Protected Sub Open()
    If _cn Is Nothing Then
        _cn = New SqlConnection(_sqlConn)
    End If

    If _cn.State = ConnectionState.Closed OrElse _cn.State = ConnectionState.Broken Then
        _cn.Open()
    End If
End Sub

This works perfectly fine during normal execution of the program. However, there are a few portions of the application that are executed in a multi-threaded fashion. When one of these parts is executing, frequent errors occur if other actions are made.

After digging a bit, I realised that this is because there were times where two different threads both attempted to use the same SqlConnection object.

So, after identifying the problem, I now need to find solutions. The obvious solution is to just re-create the SqlConnection object every time a database call requires one - in this case, it would never be shared. Is there any reason not to do this? I assumed originally that we had only one connection object per session of the application for performance reasons, but is this actually the case?

If we do need to keep just one connection object open, what is the suggested solution? Should I put in place some sort of timer which will keep cycling until the connection object is available, and then access it?

like image 872
Kiran Ramaswamy Avatar asked May 29 '14 20:05

Kiran Ramaswamy


People also ask

Is SqlConnection thread-safe C#?

Therefore, you must explicitly close the connection by calling Close. Note that SqlConnection instance is not guaranteed to be thread safe. You should avoid using the same SqlConnection in several threads at the same time. It is recommended to open a new connection per thread and to close it when the work is done.

What is the SqlConnection object used for?

A SqlConnection object represents a unique session to a SQL Server data source. With a client/server database system, it is equivalent to a network connection to the server. SqlConnection is used together with SqlDataAdapter and SqlCommand to increase performance when connecting to a Microsoft SQL Server database.

Is .NET multi threaded?

With . NET, you can write applications that perform multiple operations at the same time. Operations with the potential of holding up other operations can execute on separate threads, a process known as multithreading or free threading.

What is SqlConnection and SqlCommand in C#?

SqlConnection and SqlCommand are classes of a connected architecture and found in the System. Data. SqlClient namespace. The SqlConnection class makes a connection with the database. Further, this connection (database connection) is used by the SqlCommand to work with that database.


2 Answers

The obvious solution is to just re-create the SqlConnection object every time a database call requires one - in this case, it would never be shared. Is there any reason not to do this?

On the contrary, that's absolutely what you should do. That's the behaviour SqlConnection was designed for. You should use a Using statement to automatically close the connection at the end of the block you're using it for, and the connection pool mechanism will automatically handle the real underlying connections to the database.

like image 199
Jon Skeet Avatar answered Sep 24 '22 00:09

Jon Skeet


I see no reason NOT to create a SQL connection every time you need it. In fact, that is probably the best way to do it because it gives the .NET framework the flexibility to manage and reuse connections most efficiently. Wrap each of your SQL connections in a USING so you hang on to them as short a time as possible.

We've created a method that creates a connection and everyone uses that:

using (var conn = GetConnection())
    using (var proc = GetProcedure(conn, "procname"))
        using (var reader = proc.GetReader())
        {
            ... DB stuff
        }
like image 37
n8wrl Avatar answered Sep 25 '22 00:09

n8wrl