Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are 'using' blocks thread safe?

If I am calling some data access methods from multiple threads, do I need to lock the code around the DB calls to ensure consistency, or are the using statements below atomic?

public static DataRow GetData(Int32 id)
{
    using (SqlConnection con = new SqlConnection(connectionString);)         
    {
        con.Open();
        SqlCommand cmd = ...
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add(...)
        cmd.Parameters.Add(...)
        DataTable dt = new DataTable();
        return new SqlDataAdapter(cmd).FillWithRetry(dt, sqlGetEmail.CommandText);
    }
}

I don't think one thread can affect the connection object defined and 'in use' from another.

like image 377
Ryan Avatar asked Aug 11 '26 11:08

Ryan


2 Answers

Using statements have nothing to do with thread-safety (or lack of).

They merely ensure that Dispose method of the used object is called when the block ends; but are otherwise equivalent to a manual try..finally Dispose.

In this particular case: since a new connection is opened on each thread then it is 'thread safe'. It still might not be atomic wrt. the database or other shared state.

like image 77
user2864740 Avatar answered Aug 13 '26 16:08

user2864740


I don't think one thread can affect the connection object defined and 'in use' from another.

So I suppose you are worrying your connection's concurrent access. The using statement is not a lock. If you want to use exclusively a connection or any other instance you should use:

lock(myConnection)
{
    // your code
}

What the using keyword is for that's described here

However I think there is other misunderstandings here:. In your example your connection is a local variable what is instantiated as many times as the control flow enters to your GetData method (even in different threads). So even the control flow reenters multiple times (and in different threads) to the method, no shared connection instance will be used, each entering to the method creates its own instance.

It would be different the case if the connection instance would be a parameter. Then you should worry about concurrency, and use a lock.

Conclusion: In your sample you do NOT need to worry about your connection instance concurrent access, and you do not need to use any locking semantics.

Interestingly in your sample using of using is indeed correct, because Connection is IDisposable, so you should apply a deterministic dispose guard around its usage with try/finally or better with its shortcut: the using keyword.

like image 29
g.pickardou Avatar answered Aug 13 '26 14:08

g.pickardou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!