3

考虑以下 Perl 代码:

#!/usr/env/ perl
use strict;
use warnings;
use DBI;

my $filename = 'moo.sqlite';
my $dbh = DBI->connect("dbi:SQLite:dbname=$filename","","");
my $sql = 'INSERT into moo values (1)';
my $sth = $dbh->prepare( $sql );
my $rv = $sth->execute();
print $rv;

运行时产生此错误:

DBD::SQLite::db prepare failed: disk I/O error at test.pl line 16.
Can't call method "execute" on an undefined value at test.pl line 18.

SQLite 文件位于 SMBFS/CIFS 网络安装共享上。

我已经进行了一些跟踪,并且似乎在尝试对文件进行锁定时发生了故障:

open("moo.sqlite\0", 0x202, 0x1A4)       = 3 0
fcntl(0x3, 0x1, 0x0)         = 0 0
fcntl(0x3, 0x2, 0x1)         = 0 0

虽然我知道网络锁定是有问题的,但在交互式运行“sqlite3”二进制文件时不会出现同样的问题吗?目前,当我这样做时,我可以毫无问题地处理文件。

这是 DBI 造成的吗?

供您参考:

  • 操作系统 OS X 10.6.8
  • SQLite 版本 3.7.13
  • Perl 5.12.4
  • DBI 1.622
  • DBD::SQLite 1.37
4

1 回答 1

2

SQLite 允许多个进程一次打开数据库文件,并允许多个进程一次读取数据库。当任何进程想要写入时,它必须在其更新期间锁定整个数据库文件。但这通常只需要几毫秒。其他流程只是等待作者完成,然后继续他们的业务。其他嵌入式 SQL 数据库引擎通常只允许单个进程一次连接到数据库。

你可以试试这个,它可能会有所帮助:

my $dbh = DBI->connect("dbi:SQLite:dbname=$filename","","", "", "", {
  sqlite_use_immediate_transaction => 1,
});

问题是 CIFS 驱动程序可以配置为支持/允许锁定。如果该部分配置不正确,锁定将不起作用。

您可以尝试更改 samba 中的锁定设置:http: //oreilly.com/openbook/samba/book/ch05_05.html

尝试的最佳人选:“fake oplocks = yes”

如果它不起作用,您可以尝试在 Windows 机器上设置 ODBC 数据源并通过它访问数据库。

于 2012-10-30T15:41:53.887 回答