ADO.Net thread safety question

  • Thread starter Thread starter jzlondon
  • Start date Start date
J

jzlondon

Hi,

I have a question that I wonder if someone might be able to help me with...

I have an application which handles real-time financial data from a third
party source. The data comes in via events which are fired on an arbitrary
thread, and I then take the data, generate update commands for a SQL Server
database, and add them to a queue using a lock on a sync object to ensure
thread safety when writing to the queue.

I then have a background worker thread which watches the queue and executes
the queries inside it sequentially. Again, the reading and dequeuing is
synchronised with the writing.

So far, so good.

I also have a need to execute some other, fairly slow running, queries
against the database. These queries will return results and will be running
in an arbitrary thread. The question I have is about thread safety around
the SQLConnection object. So far, I've avoided locking on it, as I only
have one thread (the worker) accessing it at any point.

Do I need to synchronise access to the connection object? If so, can I open
a separate connection and sync that, leaving the first connection free to
process the updates, or will connection pooling interfere and give me any
problems?

Thanks in advance for any advice you may have,

James Cane

ps. .Net 2.0, C#, SQL Server 2005.
 
jzlondon said:
Hi,

I have a question that I wonder if someone might be able to help me with...

I have an application which handles real-time financial data from a third
party source. The data comes in via events which are fired on an arbitrary
thread, and I then take the data, generate update commands for a SQL Server
database, and add them to a queue using a lock on a sync object to ensure
thread safety when writing to the queue.

I then have a background worker thread which watches the queue and executes
the queries inside it sequentially. Again, the reading and dequeuing is
synchronised with the writing.

So far, so good.

I also have a need to execute some other, fairly slow running, queries
against the database. These queries will return results and will be running
in an arbitrary thread. The question I have is about thread safety around
the SQLConnection object. So far, I've avoided locking on it, as I only
have one thread (the worker) accessing it at any point.

Do I need to synchronise access to the connection object? If so, can I open
a separate connection and sync that, leaving the first connection free to
process the updates, or will connection pooling interfere and give me any
problems?

Thanks in advance for any advice you may have,

James Cane

ps. .Net 2.0, C#, SQL Server 2005.


Hi,
Just for precaution, I think you should sync the connection
object. Actually, I faced a lot of weird errors which originated from
these kind of thread sync problem. The queries don't execute when such
exceptions occur. As you told that the application was related to some
financial domain, I would stress on synchronizing the connection
object.
If you don't want to synchronize connection object then, you will
have to open create and use new connection object each time when you
want to fire some query. To read more about my personal experience
about the exceptions please visit my blog -
http://anants-blog.blogspot.com/

Hope you don't get such kind of errors !

Thanks !
 
jzlondon said:
Do I need to synchronise access to the connection object? If so, can I open
a separate connection and sync that, leaving the first connection free to
process the updates, or will connection pooling interfere and give me any
problems?

James,

You need to synchronize access to a SqlConnection object only when it
is accessed from more than one thread. The presence of a connection
pool does not change that rule. If you have gotten in the habit of
ensuring that all SqlConnection objects are local to a method then
you're fine.

Brian
 
Hi Brian,

Thanks. It will be accessed from more than one thread.

The reason for this is that I'm reusing a connection to save some overhead
(at peak times, I can be generating almost 1000 database updates per
second).

The reason I was asking about the thread safety with connection pooling is
that, if I'm not mistaken, connection pooling works by allocating a
pre-existing connection when you request a new one. My concern is that two
separate threads could request a new connection, but each could receive the
same connection from the pool.

In this case, you'd think there'd be no need to sync the connection, as it's
local to the method, but it actually represents an underlying shared object
and concurrency issues may arise.
 
JamesC said:
Hi Brian,

Thanks. It will be accessed from more than one thread.

Then you definitely need to synchronize access to it.
The reason for this is that I'm reusing a connection to save some overhead
(at peak times, I can be generating almost 1000 database updates per
second).

The reason I was asking about the thread safety with connection pooling is
that, if I'm not mistaken, connection pooling works by allocating a
pre-existing connection when you request a new one. My concern is that two
separate threads could request a new connection, but each could receive the
same connection from the pool.

Basically what happens is that Open attempts to acquire a connection
from the pool. Once the connection is acquired it is removed (or
marked as unavailable). If no connection is available then a new one
is established. When Close or Dispose is called the connection is then
returned (or marked as available) to the pool. The connection pool
manager itself is thread-safe so two simultaneous calls to Open from
two different SqlConnection objects will race for an available
connection from the pool, but only one will win resulting in the other
having to establish a brand new connection. In other words, two
different SqlConnection objects cannot simultaneously hold the same
underlying connection.
 
That's awesome. Not only is that a clear and knowledgeable answer, it's
also the answer I was hoping for!

Thanks Brian

James
 
Back
Top