3

我在 PHP-PDO-SQLite 中的事务和更新有问题。

$db = new PDO('sqlite:database1.sqlite');

/*
$rowsnumber1 = $db->exec("CREATE TABLE IF NOT EXISTS questions(
id INTEGER PRIMARY KEY AUTOINCREMENT,
question TEXT NOT NULL,
answers INTEGER NOT NULL
)");
print('$rowsnumber1: '.$rowsnumber1.'<br />');

$rowsnumber2 = $db->exec("CREATE TABLE IF NOT EXISTS answers(
id INTEGER PRIMARY KEY AUTOINCREMENT,
qid INTEGER NOT NULL,
answer TEXT NOT NULL
)");
print('$rowsnumber2: '.$rowsnumber2.'<br />');
*/

//print('Inserting: '); $res = $db->exec("INSERT INTO questions (question,answers) VALUES ('Question',0)"); var_dump($res); print('<br />');

$qid = 1;

try
{
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$db->beginTransaction();

// Variant 1
//print('Executing 1: '); $res1 = $db->exec("INSERT INTO answers (qid,answer) VALUES ($qid,'Answer')"); var_dump($res1); print('<br />');
//print('Executing 2: '); $res2 = $db->exec("UPDATE questions SET answers = answers+1 WHERE id = '".$qid."'"); var_dump($res2); print('<br />');

// Variant 2
print('Preparing 1: '); $statement1 = $db->prepare("INSERT INTO answers (qid,answer) VALUES (:qid,:answer)"); var_dump($statement1); print('<br />');
print('Preparing 2: '); $statement2 = $db->prepare("UPDATE questions SET answers = answers+1 WHERE id='".$qid."'"); var_dump($statement2); print('<br />');

print('Executing 1: '); $res1 = $statement1->execute(array('qid'=>$qid,'answer'=>'Answer')); var_dump($res1); print('<br />');
print('Executing 2: '); $res2 = $statement2->execute(); var_dump($res2); print('<br />');

$db->commit();
}
catch(Exception $e)
{
$db->rollBack();
print("Transaction failed: " .$e->getMessage());
}

当问题的“id”和答案的“qid”相同($qid)时,没有问题。当我尝试插入带有问题“id”的答案时,问题就开始了,该问题在“问题”表中不存在。例如,在“问题”表中有一个问题(“id”为“1”),您尝试用“id”=“5”插入问题的答案。答案被插入,但问题没有更新(单元格“答案”没有增加),因为没有这样的“id”=“5”的问题。问题是事务不会进行回滚,并且执行更新时结果为“true”,尽管实际上没有更新。交易有什么问题以及为什么更新返回“true”

4

2 回答 2

1

我已经明白我做错了什么。问题是“尝试”部分没有逻辑。$db->commit(); 之前 我应该写下两行:

if($res1 != 1) throw new Exception("Inserting the answer failed");
if($res2 != 1) throw new Exception("Updating the question failed");

关于准备();并执行();- 我在这里漫不经心地阅读了 PDO 的手册http://www.php.net/manual/en/pdostatement.execute.php 问题是execute(); 如果语句被执行,则返回“true”,但不检查它是否影响了一行。和方法 exec(); 检查该行是否受到影响。即方法prepare(); 并执行();不适合这种情况。我应该使用我评论过的“变体 1”。

于 2013-05-11T05:40:12.030 回答
0

我有类似的问题,只有在允许写访问问题仍然存在之后。

显然,我在提交失败的事务中出现“外键约束失败”错误。

我必须把我的数据库表弄直,问题就解决了。

我希望这可以帮助别人。

于 2015-09-08T10:37:55.850 回答