Pdo 3,多次运行:错误:17数据库模式已更改

时间:2014-12-26 16:57:39

标签: php sqlite pdo

我有这个测试代码:

session_start();
session_write_close();
set_time_limit(0);

for ($i = 1; $i < 1000; $i++)
{
    if (rand(1,5) == 1)
    {
        $file_db = new PDO('sqlite:x.db');
        $file_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $file_db->exec('DROP TABLE IF EXISTS messages');
        $file_db = null;
    }
    $file_db = new PDO('sqlite:x.db');
    $file_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $file_db->exec('CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY AUTOINCREMENT,title TEXT,message TEXT,time INTEGER)');
    $file_db->query('INSERT INTO messages VALUES (null, "'.rand(1,9999).'", "'.rand(1,99).'", date("now"))');
    $file_db = null;
}

$file_db = new PDO('sqlite:x.db');
$file_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$i = 0;
foreach ($file_db->query('SELECT * FROM messages') as $m)
{
    $i++;
    echo $i.' -> '.$m['id'].'<br>';
}

使用此代码我测试PDO 3是否适用于多个并发。如果此代码在一个线程中运行,则一切正常。但是,只要我开始两个这样的实例,我就会得到这样的信息:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 17 database schema has changed' in code.php:* Stack trace: #0 code.php(*): PDO->query('INSERT INTO mes...') #1 {main} thrown in code.php on line *

错误行是INSERT INTO的位置。为什么会发生这种情况以及如何避开它? (我创建了一个缓存系统,其中有可能创建和删除表。我知道有TRUNCATE,我只想知道为什么会这样)

2 个答案:

答案 0 :(得分:5)

  

[...]一旦我启动了两个这样的实例,我收到此消息:[...] SQLSTATE [HY000]:一般错误:17数据库模式已更改[...]为什么会发生这种情况以及如何躲闪它?

Sqlite是一个单一文件数据库。您可以并行打开它,然后更改数据库结构。您刚刚删除表格以插入 时插入数据不起作用 因为表格已消失。这就解释了为什么会发生这种情况。

正如您希望现在已经明白无法插入到不存在的表中一样,解决方案可能清晰可见:仅插入现有表中。

为确保您在删除表格后创建表格,在交易中执行此类操作可能会有所帮助:https://www.sqlite.org/lang_transaction.html

答案 1 :(得分:1)

尝试
$ file_db = new PDO(realpath(&#39; sqlite:x.db&#39;)); 对于
$ file_db = new PDO(&#39; sqlite:x.db&#39;);