作者:我跟孔子一个姓 | 来源:互联网 | 2023-05-29 14:22
我有这个测试代码:
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'].'
';
}
使用此代码我测试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,我只想知道为什么会这样)
1> hakre..:
[...]一旦我开始这个实例的两个实例,我得到这样的消息:[...] SQLSTATE [HY000]:一般错误:17数据库模式已经改变[...]为什么会发生这种情况以及如何躲闪吧?
Sqlite是一个单一文件数据库.您可以并行打开它,然后更改数据库结构.您刚刚删除要插入的表时插入数据不起作用,因为表已经消失.这解释了它为什么会发生.
正如您希望现在已经明白无法插入到不存在的表中一样,解决方案可能清晰可见:仅插入现有表中.
为确保在删除表后创建表,在事务中执行此类操作可能会有所帮助:https://www.sqlite.org/lang_transaction.html