我有一个PHP脚本,每个循环使用预准备语句执行大约1,000次插入和1,000次更新。只要工作需要完成,有时需要几个小时,它就会循环,并导致性能问题(包括死锁异常)。
我正在尝试提高性能,并正在研究批量插入和更新(尽管我仍然在试图弄清楚如何进行批量更新)。
当调用PDO::beginTransaction()
时,它是否只是告诉PDO类不向数据库发送除PDO::execute()
之外的查询,或者是否发送查询然后锁定使用的表/行直到{ {1}}被称为?
我问的原因是PHP脚本每个循环最多占用50秒,它会在该时间跨度内进行插入和更新查询,所以我试图找出是否可以简单地添加{{1在脚本的开头和最后的PDO::commit()
。
答案 0 :(得分:1)
实际上PDO::beginTransaction()
遵循与MySQL中START TRANSACTION
语句相同的规则,更多信息here。
这意味着MySQL不会立即锁定表格,但会遵循ACID规则。
请注意,如果您需要显式锁定某些表,您可以这样做:
$db->beginTransaction();
$db->exec('LOCK TABLES t1, t2, ...');
答案 1 :(得分:1)
PDO::beginTransaction()
基本上是autocommit mode
。当您开始交易($mydb->beginTransaction();
)时,表示您关闭 PDO AutoCommit。
并且,在您通过提交或回滚之前停止继续进行交易。
例如$mydb->commit();
当你停止它时,它将再次变为自动提交。
在这里,您可以使用提交或回滚来控制事务。
关于您需要处理大量查询的问题,我建议您根据优先级逐步执行此操作,如下所示:
// start your transaction - means - stop auto commit.
If(query1 gets successful){
If(query2 gets successful)
{
// Commit the transaction // stop the transaction
}
else
{
// Roll back the transaction
}
}
else{
// Rollback the transaction
}
请注意使用PDO事务,因为结果无法撤消。请参阅此ref:http://php.net/manual/en/pdo.transactions.php