Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / April 2006

Tip: Looking for answers? Try searching our database.

Web Service, Multithreaded, Logging to Database

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Stephen Carson - 05 Apr 2006 21:17 GMT
I'm trying to build a Web Service that will kick off threads as logging
requests come in. These threads will then log to the database. I have
been able to make a simple Web Service. I have been able to get a
simple multi-threaded example working. I have been used the
SqlDataAdapter and DataSet classes extensively to access databases in a
deployed Windows Service. But I'm getting confused how to put the
pieces together.

For example, I want to make the class that I'm going to hand off to the
thread able to access the database. The way I learned to do that is
with a Component Class:
    __gc public class LogItem :  public System::ComponentModel::Component

But in the docs, I note this:
"Any public static (Shared in Visual Basic) members of this type are
safe for multithreaded operations. Any instance members are not
guaranteed to be thread safe."

But that makes the Component Class pretty darn useless for my purpose.
How do I do thread safe database access?

If anyone has seen an example of a multi-threaded Web Service talking
to a DB, please let me know. It seems like a fairly obvious thing to do
with a Web Service.

Thanks,
Stephen W. Carson
Tamas Demjen - 06 Apr 2006 17:39 GMT
> But in the docs, I note this:
> "Any public static (Shared in Visual Basic) members of this type are
> safe for multithreaded operations. Any instance members are not
> guaranteed to be thread safe."

When we say something is not thread safe, it doesn't mean it can't be
used in a thread. It just means that if two threads write the same
object at the same time, you'll get into an undefined state. As long as
the object is used exclusively by a single thread only, you don't have
to worry about thread safety issues. If an object is shared by multiple
threads, you have to ensure mutual exclusivity on your own (for example,
by using a critical section). Most objects are thread unsafe, because
it's a tremendous overhead to add thread safety, and only you can do it
efficienty at the application level. Those who created the objects don't
know anything about your threads and how they interact.

> But that makes the Component Class pretty darn useless for my purpose.
> How do I do thread safe database access?

That has nothing to do with the component, it has to do with the
database. Which database are you using? There are single-user (embedded)
databases, which lock the database while it's open, thus not allowing
anyone else to open it. Those are usually very lightweight databases and
pretty useless in your case. However, every serious database engine
designed for a multiuser environment supports transactions and access to
the engine by multiple threads at the same time.

What you can't do is to drop a single database component on your form,
and access that by multiple threads at the same time. But if you create
a dedicated database logger for each of your threads, they won't
conflict. Your LogItem object should be a private member of your thread,
inaccessible from the outside, and you'll be fine.

In other words, you can access a database by multiple threads, but each
thread has to use its own database component, because the database
access component itself is not thread safe, the database engine usually
is, except those ultra-thin embedded engines.

Tom
Stephen Carson - 06 Apr 2006 20:17 GMT
> > But in the docs, I note this:
> > "Any public static (Shared in Visual Basic) members of this type are
[quoted text clipped - 6 lines]
> the object is used exclusively by a single thread only, you don't have
> to worry about thread safety issues.

You've cleared up my confusion here. I was reading "not thread safe" as
"don't use this in a multi-threaded environment at all".

> > But that makes the Component Class pretty darn useless for my purpose.
> > How do I do thread safe database access?
[quoted text clipped - 6 lines]
> designed for a multiuser environment supports transactions and access to
> the engine by multiple threads at the same time.

We're using SQL Server so I'm sure the database can handle it.

> What you can't do is to drop a single database component on your form,
> and access that by multiple threads at the same time. But if you create
[quoted text clipped - 6 lines]
> access component itself is not thread safe, the database engine usually
> is, except those ultra-thin embedded engines.

OK, I believe my approach is going to work then. The basic idea is that
for each logging request that comes in, a LogItem object is created and
handed off to a thread, like so:
        LogItem * logItem = new LogItem(various,info,to,log);
        Thread * thread = new Thread ( new ThreadStart( logItem,
&LogItem::LogIt ) );
        thread->Start();

The actual database access would happen inside LogIt() with each
logItem object having its own sqlDataAdapter object, etc.

Sound like I'm on the right track?

Thanks very much for your lengthy and very helpful reply!

Stephen W. Carson
Carl Daniel [VC++ MVP] - 06 Apr 2006 20:30 GMT
> Sound like I'm on the right track?

Yes, that should work fine.

You should be aware of potential deadlock issues between multiple database
accessors.  For a logging scenario, I'd expect that you'll be using
connections that are in auto-commit mode (no explicit transaction), and that
the loggers will basically be doing insert-only transactions.  In that case,
there's nothing to worry about with regard to deadlocks.

-cd
Stephen Carson - 06 Apr 2006 22:52 GMT
> You should be aware of potential deadlock issues between multiple database
> accessors.  For a logging scenario, I'd expect that you'll be using
> connections that are in auto-commit mode (no explicit transaction), and that
> the loggers will basically be doing insert-only transactions.  In that case,
> there's nothing to worry about with regard to deadlocks.

Insert-only transactions are exactly what I'm planning on doing. Is
there anything special I need to do to ensure my connections are in
"auto-commit mode"? I'm making use of the auto-generated DataSet like
so:

        DataRow * newRow = dsTest1->Tables->Item["SWC_Test"]->NewRow();
        newRow->Item["French"] = m_temp;
        dsTest1->Tables->Item["SWC_Test"]->Rows->Add(newRow);
Carl Daniel [VC++ MVP] - 07 Apr 2006 03:01 GMT
>> You should be aware of potential deadlock issues between multiple
>> database accessors.  For a logging scenario, I'd expect that you'll
[quoted text clipped - 6 lines]
> there anything special I need to do to ensure my connections are in
> "auto-commit mode"?

No.  Unless you take specific steps to make it otherwise, your connections
will be auto-commit.

-cd
Stephen Carson - 07 Apr 2006 15:27 GMT
Thanks very much to Tamas and Carl for their help. I got a little toy
Web Service working last night that launches off a DB inserting thread
for each request. I then put in a little loop to rapid fire launch 100
of these threads. They all wrote to the database with no problem. 100
in less than a second is way better performance than I expect to need
for this service so this is looking like a robust logging solution.

Stephen W. Carson

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.