【问题标题】:Limits of multithreaded INSERTS in sqlitesqlite 中多线程 INSERTS 的限制
【发布时间】:2011-07-11 15:50:59
【问题描述】:

我的 perl 脚本是多线程的,在每个线程中我必须向 sqlite3 数据库写入一些内容。但正如你可能猜到的,我得到了很多

DBD::SQLite::db 失败:数据库在 script.pl 第 264 行被锁定。

消息。我读到 sqlite3 能够处理多线程情况,甚至是 INSERT 语句,但我认为在同时插入 8 个线程时我期望很高。

好的,所以这是不可能的,但是否有可能在插入之前执行检查以查看数据库是否已锁定(或忙碌)然后等到再次空闲?

我真的不想更改为“真正的”DBMS,因为它只是一个简单的脚本。

谢谢

【问题讨论】:

  • 您可以发布任何代码吗?与其他语言中的多线程相比,Perl 中的多线程有很多限制。我希望必须做很多杂技才能从一个线程更新到 SQLite 数据库以被另一个线程识别。

标签: perl sqlite


【解决方案1】:

如果你需要阻塞直到你可以访问数据库,尝试独占事务,即,

$dbh->do("begin exclusive transaction") or die $dbh->errstr;
#inserts here
$dbh->do("commit transaction") or die $dbh->errstr;

这样,您将锁定委托给 SQLite,而不是在 Perl 中进行。由于各种原因,这更安全,尤其是您可能在 Perl 以外的其他地方打开数据库,或者在另一个 Perl 进程而不是线程中打开数据库。

而且,正如@mob 评论的那样,Perl 线程是一个有点滑稽的野兽。我只是让它所属的数据库完成锁定。

【讨论】:

  • 这对我不起作用。即使添加此内容后,我也会收到“数据库已锁定”警告/错误。即使那是我应该预料到的,它也不是我需要的。 :) 顺便说一句,它必须是“$dbh->do("commit") or die $dbh->errstr;"最后,否则我会收到语法错误。
  • 等一下,我想我只是做错了。稍后会回来。
  • 正确的提交语句应该是“提交事务”而不是“提交独占事务”,至少在我的 Sqlite3 DB 上是这样。
【解决方案2】:

写入数据库时​​,SQLite 使用 fcntl() 锁定整个数据库文件。当另一个进程/线程尝试写入它时,它将等待一段时间(30 秒?)然后放弃。请参阅SQLiteFAQ

请注意,虽然 Perl 的线程确实有缺陷和怪异,但这不是这里的根本问题。我认为 SQLite 对于除了最简单的需求之外的所有需求都是不合适的选择。

【讨论】:

  • 也许您对 sqlite 的看法是正确的,但有什么替代方案?就我的目的而言,使用真正的 RDBMS 会非常重要。你用什么?
  • 不幸的是,没有,至少就我所见而言。 MySQL 是最接近的解决方案。
【解决方案3】:

一种替代方法可能是让每个线程插入到自己的暂存表中,然后在变量上使用lock(可以使用虚拟变量)并在线程有锁时插入到最终表中。换句话说,类似...

sub ThreadStuff
{
    my $tid=threads->tid;
    #Thread is doing whatever it's doing
    $dbh->do("delete from staging_" . $tid) or die $dbh->errstr;
    $dbh->do("insert into staging_" . $tid . "stuff;") or die $dbh->errstr;

    {
        lock $hall_pass;
        $dbh->do("insert into final_table select * from staging_" . $tid) or die $dbh->errstr;
        #The lock on $hall_pass goes away as soon as we leave this block.
    }
    #Other stuff, maybe cleanup or whatever.
}

【讨论】:

  • 嗨,杰克,我可以要求解释一下代码吗?为什么我需要临时表?为什么不能直接在主表中阻止然后插入?对不起,如果这是一个转储问题,我想我错过了一些东西。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2015-11-01
  • 1970-01-01
相关资源
最近更新 更多