SQLite 数据库中的递归被锁定
Recursion in SQLite Database is locked
我使用 SQLite 构建类似树的东西。
我在我的任务中使用递归:
$this->recursion($row['id']...
我的代码在旧 MySQL 中有效,但在 SQLite 中无效。
我收到致命错误:数据库被锁定在...我有 INSERT 的行。
因为 SELECT 连接在 INSERT 之前使用数据库。
而PHP只插入一条记录。
我使用了 BeginTransaction 和 Commit,我使用了 busyTimeout。它对我没有帮助。
public function recursion($from, $to){
$db = new SQLite3("db.sqlite");
$stmt = $db->prepare('SELECT value, s_id, sex FROM table WHERE id='. $from);
$result = $stmt->execute();
$row = $result->fetchArray();
//'database is locked' in next line
$db->exec('INSERT INTO table (id, s_id, value) VALUES (null,'. $to . $row['value'] .'");');
if ($row['sex']=='fem'){
$stmt = $db->prepare('SELECT id FROM table WHERE s_id=' . $from);
$result = $stmt->execute();
while ($row = $result->fetchArray()){
$this->recursion($row['id'], $db->lastInsertRowID());
}
}
}
public function recursion($from, $to){
$res=mysql_connect($mysql_server,$mysql_user,$mysql_pass);
mysql_select_db($mysql_db);
$sql = 'SELECT value, s_id, s_id, sex FROM table WHERE id='. $from;
$result = mysql_query($sql, $res);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
mysql_query('INSERT INTO table (id, s_id, value) VALUES (null,'. $to . $row['value'] .'");', $res);
if ($row['sex']=='fem'){
$sql = 'SELECT id FROM table WHERE s_id=' . $from;
$result = mysql_query($sql, $res);
while ( $row = mysql_fetch_array($result, MYSQL_ASSOC) ) {
$this->recursion($row['id'], mysql_insert_id());
}
}
}
我重复一下,我的代码在 MySQL 中有效。
有什么想法吗?有什么提示吗?
谢谢
您正在递归函数内部进行连接。第一次调用将 open/lock 数据库。第一次递归调用将尝试重新打开数据库,但失败了,因为它已经在父上下文中打开了。 MySQL 代码之所以有效,是因为您的递归深度不足以达到其连接限制。
您应该在递归函数之外打开一次数据库,然后在每个递归级别重复使用该句柄。 MySQL 也一样。
很少有理由打开多个数据库连接。大约唯一合理的时间是您需要使用不同的客户端凭据进行连接。
我使用 SQLite 构建类似树的东西。 我在我的任务中使用递归:
$this->recursion($row['id']...
我的代码在旧 MySQL 中有效,但在 SQLite 中无效。
我收到致命错误:数据库被锁定在...我有 INSERT 的行。
因为 SELECT 连接在 INSERT 之前使用数据库。
而PHP只插入一条记录。
我使用了 BeginTransaction 和 Commit,我使用了 busyTimeout。它对我没有帮助。
public function recursion($from, $to){
$db = new SQLite3("db.sqlite");
$stmt = $db->prepare('SELECT value, s_id, sex FROM table WHERE id='. $from);
$result = $stmt->execute();
$row = $result->fetchArray();
//'database is locked' in next line
$db->exec('INSERT INTO table (id, s_id, value) VALUES (null,'. $to . $row['value'] .'");');
if ($row['sex']=='fem'){
$stmt = $db->prepare('SELECT id FROM table WHERE s_id=' . $from);
$result = $stmt->execute();
while ($row = $result->fetchArray()){
$this->recursion($row['id'], $db->lastInsertRowID());
}
}
}
public function recursion($from, $to){
$res=mysql_connect($mysql_server,$mysql_user,$mysql_pass);
mysql_select_db($mysql_db);
$sql = 'SELECT value, s_id, s_id, sex FROM table WHERE id='. $from;
$result = mysql_query($sql, $res);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
mysql_query('INSERT INTO table (id, s_id, value) VALUES (null,'. $to . $row['value'] .'");', $res);
if ($row['sex']=='fem'){
$sql = 'SELECT id FROM table WHERE s_id=' . $from;
$result = mysql_query($sql, $res);
while ( $row = mysql_fetch_array($result, MYSQL_ASSOC) ) {
$this->recursion($row['id'], mysql_insert_id());
}
}
}
我重复一下,我的代码在 MySQL 中有效。
有什么想法吗?有什么提示吗? 谢谢
您正在递归函数内部进行连接。第一次调用将 open/lock 数据库。第一次递归调用将尝试重新打开数据库,但失败了,因为它已经在父上下文中打开了。 MySQL 代码之所以有效,是因为您的递归深度不足以达到其连接限制。
您应该在递归函数之外打开一次数据库,然后在每个递归级别重复使用该句柄。 MySQL 也一样。
很少有理由打开多个数据库连接。大约唯一合理的时间是您需要使用不同的客户端凭据进行连接。