在代码中实现多线程包含SQL调用

时间:2014-01-30 10:01:54

标签: perl perl-module

我想在我的代码中实现多线程以减少时间。我实现了Thread :: Queue,但是我收到错误因为代码包含SQL查询。我无法同时通过线程访问数据库。

  sub worker{ 
    while($q->queue){
if (exists $href->{$issue}->{'parent'}) {
        foreach my $parent (sort keys %{$href->{$issue}->{'ddts_parent'}}) {
        my $sql_dest1 ="select pkey from jiraissue where ID=(Select Query')";
            my $sth_dest1 = $dbh->prepare($sql_dest1);
            $sth_dest1->execute();

            foreach (my $dest_array = $sth_dest1->fetchrow_array) {
                if ($dest_array ne '') {
------------some code here------------------------------
                        #to retain link between projects and delete Active url.
                        my $remote_key=$dbh->selectrow_array("select Query)");
                        my $temp_ddtsid=$dbh->selectrow_array("select Query')");
                            $jira->update_issue($remote_key,$update);
                        }
                }   
                else {  
                        $jira->update_issue($src_issue,$update);
                    }
                }           
            }
        }       
    } 
    if (exists $href->{$src_issue}->{'ddts_child'}) { 
        foreach my $ddts_child (sort keys %{$href->{$src_issue}->{'ddts_child'}}) { 
            my $sql_dest ="select Query')";         
            my $sth_dest = $dbh->prepare($sql_dest);
            $sth_dest->execute();


            foreach (my $dest_array = $sth_dest->fetchrow_array) {
                if ($dest_array ne '') {

                            $jira->update_issue($src_issue,$update);
                        }
                        #to retain link between projects and delete Active url.
                        my $remote_key=$dbh->selectrow_array("select Query");
                    my $temp_ddtsid=$dbh->selectrow_array("select Query");

        }
    } 

请给我一个如何实现多线程和信号量的解决方案。

1 个答案:

答案 0 :(得分:1)

来自Threads and Thread Safety in the DBI documentation,强调我的:

  

[当创建一个新线程时,将克隆包含其所有数据的整个解释器。]

     

但是,句柄中的内部指针数据将引用原始解释器中的DBI和驱动程序。在新的解释器线程中使用这些句柄是不安全的,因此DBI使用不属于当前线程的句柄(任何DESTROY除外)检测到这个和在任何方法调用上的表示。

     

由于这种(可能是临时的)限制,新创建的线程必须与数据库建立自己的连接。句柄不能跨线程共享

     

但是BEWARE,一些底层数据库API (DBD驱动程序用来与数据库通信的代码,通常由数据库供应商提供)不是线程安全的。如果它不是线程安全的,那么允许多个线程同时输入代码可能会导致细微/严重的问题。在某些情况下,允许多个线程输入代码,即使不是同时,也可能导致问题。 您已收到警告

     

建议不要在生产环境中使用带有perl线程的DBI。有关详细信息,请参阅http://www.perlmonks.org/index.pl?node_id=288022

总结:

  • 原则上,DBI可以在多线程环境中工作,只要底层驱动程序也是线程安全的。
  • 您必须为每个线程创建一个新连接。无法在线程之间共享连接,语句句柄和结果句柄。