expresspotato has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks! I need some help with threads, DBI and overall effectiveness of using mysql with perl. I'm just finding out that perl DBI might not be thread safe, I often get errors logged that "$dbh not owned by X(pid), DESTROY Ignored" or something to that extent. My program is slowly but surely growing in size and makes heavy use of threads to process things in a timely manner. Here's sample code used to process requests as they occur.
use DBI; use threads qw(stringify); use threads::shared; use Time::HiRes qw (sleep); do("./sql.pl"); &sql_setup; $server_id = "A"; share($server_id); $sys_ok = 1; share($sys_ok); $|++; $thr1 = threads->new(\&starter); $thr1->detach; $thr2 = threads->new(\&stopper); $thr2->detach; $thr3 = threads->new(\&monitor); $thr3->detach; $thr4 = threads->new(\&processor); $thr4->detach;
As these treads are run, their subroutines pickup tasks to be processed then simply exit. My guess is while one $dbh is executing, another is called and when the first is finished, its no longer assigned to the same handle and thus crashes. Now here is the second part to my question... Is there a better way to use perl DBI when making multiple queries rather than constantly creating more than one $dbh? For example, when executing one query and data needs to be pulled from a second table, rather than creating $dbh2...? Here's some of the code contained in sql.pl used in the processing of queries.
sub row_sql(){ my $select = $_[0]; my @row2,$dbh2,$sth2; if ($select eq ""){print "Empty Select."; exit;} $dbh2=DBI->connect($connectionInfo,$user,$passwd) || print "DBI Conn +ection Failed!($DBI::errstr)"; $sth2=$dbh2->prepare($select); if (!($sth2->execute())) { } @row2=$sth2->fetchrow_array(); $sth2->finish; $dbh2->disconnect(); return (@row2); }
So to sum up two questions: 1. Is there a thread safe DBI or way to use DBI within multiple threads and processes? 2. Is there a better way to run a query inside a query without having to pre-define $dbh1 $dbh2 $dbh3? Thank you for your help and hope to hear from you soon.

Replies are listed 'Best First'.
Re: Threads, MySQL & Ease of use
by Corion (Patriarch) on Jun 26, 2009 at 07:38 UTC

    Read the DBI documentation on threads. In general, it's just a bad idea to access your database through more than one thread. Also, what benefit do you expect from running more than one query at a time?

Re: Threads, MySQL & Ease of use
by BrowserUk (Patriarch) on Jun 26, 2009 at 08:46 UTC

    Question: Why do you declare and share

    $server_id = "A"; share($server_id);

    instead of declaring shared: my $server_id :shared = 'A';?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Threads, MySQL & Ease of use
by imrags (Monk) on Jun 26, 2009 at 05:35 UTC
    I've not used Threads with DBI, however, from whatever threads i've used so far,
    I've always found it useful to use threads with semaphore and control the
    number of threads accessing a particular subroutine.
    Also be careful of using threads on windows box with multiple CPUs. You also have to be careful
    about the memory used by threads!
    Raghu