我有这个测试代码:
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,我只想知道为什么会这样)
答案 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;);