Perl DBD :: SQLite - 外部的begin_work,而循环阻塞线程?

时间:2014-02-26 21:58:07

标签: multithreading perl sqlite loops dbi

我有一个使用Perl线程模块创建许多线程的脚本,每个线程都创建一个到SQLite dbfile的数据库连接。在线程内部有一个while循环读取文件句柄,打开管道输入到正在使用zcat处理的文件。我正在尝试每个线程处理每个X行的事务。当我尝试在while循环之外使用$dbh->begin_work时,单个线程会阻塞其余部分。当我将$dbh->begin_work置于while循环中时,它们不会相互阻塞。后者基本上是自动提交每个$dbh->do("insert...")语句。为什么$dbh->begin_work似乎不能在while循环之外工作?

$dbh->begin_work; # This blocks the while loops in other threads

while ($row = <$gz>) {
  $dbh->begin_work; # This does not block
  @values = split('\|', $row);
  @node_ids = split ',', $values[21]
  for $node_id (@node_ids) {
    $dbh->do("insert ....");
  }
  $dbh->commit; # This does not block
}

$dbh->commit; # This blocks the while loops in other threads

我目前正在使用DBD:SQLite版本1.29。我尝试使用* sqlite_use_immediate_transaction *但在版本1.38_01之前似乎没有必要。

1 个答案:

答案 0 :(得分:0)

我所有的锁定经验都在其他数据库中,我不确定您的期望(在我看来,begin_work按设计工作)但是如果你把它放在:

unless (++$count % X) { $dbh->commit; $dbh->begin_work; }

在插入之后,删除循环内的其他commit / begin,它似乎会做你想要的,释放锁并进入下一组锁的队列。