运行Strawberry Perl 5.24的Windows 10计算机上的以下代码失败:
使用DBI;
unlink glob(“*。db3”);my $ source = DBI-> connect(“dbi:SQLite:dbname = first.db3”,q(),q(),{AutoCommit => 0,…
根据 文件 , 什么时候 AutoCommit 模式已关闭:
AutoCommit
SQLite的默认事务行为是延迟的,这意味着,在第一次读取或写入操作之前不会获取锁定,因此有可能另一个线程或进程可以创建单独的事务并在当前的BEGIN之后写入数据库线程已执行,并最终导致“死锁”。为避免这种情况,如果您通过调用begin_work或关闭AutoCommit(自1.38_01)开始事务,DBD :: SQLite会在内部发出BEGIN IMMEDIATE。 如果由于某些原因确实需要关闭此功能,请将sqlite_use_immediate_transaction数据库句柄属性设置为false,并使用默认的延迟事务。
SQLite的默认事务行为是延迟的,这意味着,在第一次读取或写入操作之前不会获取锁定,因此有可能另一个线程或进程可以创建单独的事务并在当前的BEGIN之后写入数据库线程已执行,并最终导致“死锁”。为避免这种情况,如果您通过调用begin_work或关闭AutoCommit(自1.38_01)开始事务,DBD :: SQLite会在内部发出BEGIN IMMEDIATE。
如果由于某些原因确实需要关闭此功能,请将sqlite_use_immediate_transaction数据库句柄属性设置为false,并使用默认的延迟事务。
(这似乎是不受欢迎的行为,也许是因为我累了,但我不知道你怎么会遇到死锁;只是在尝试锁定已被另一个连接锁定的数据库时出错)
但无论如何:
$ sqlite3 second.db3 sqlite> attach database 'first.db3' as chunk_db; sqlite> begin immediate; sqlite> detach database chunk_db; Error: database chunk_db is locked
看起来很熟悉......
默认行为时 AutoCommit 关闭意味着你 总是 在与被收购者的交易中 保留锁定 。你看到这有一些不寻常的副作用。
那么,按我的偏好顺序排列的解决方案:
$dbh->begin_work
DETACH
sqlite_use_immediate_transaction