我的PHP / Mysql脚本分阶段运行:
Insert Customer info
Get new customer's ID via mysqli_insert_id(blah)
Insert into ADDRESS using new customer's ID
Insert into PHONE using new customer's ID
Insert into CONTACTS using new customer's ID
我的问题是:如果后面的一个插入语句出现问题,MYSQL当然会停止并抛出错误,但初始的Customer INSERT已经触发并且成功了。现在,如果我们返回并更正输入中的错误并尝试再次执行此操作,我们将为此客户提供多个部分条目。
所以问题:有没有办法测试所有MySQL插件的错误,一旦找不到,那么继续提交它们吗?
例如:
Insert Customer info (check for would-be errors; don't actually insert)
Get new customer's ID...
Insert into ADDRESS...(check for would-be errors; don't actually insert)
Insert into PHONE...(check for would-be errors; don't actually insert)
Insert into CONTACTS...(check for would-be errors; don't actually insert)
好的,既然没有抛出任何错误而且实际上没有插入任何内容,请执行所有预先筛选的插入!
这是否存在?
答案 0 :(得分:4)
使用MySQL事务。
事务是一组连续的数据库操作操作,就像它是一个单独的工作单元一样。换句话说,除非组内的每个单独操作都成功,否则交易永远不会完成。如果事务中的任何操作失败,整个事务将失败。
实际上,您会将许多SQL查询添加到一个组中,并且您将作为事务的一部分一起执行所有这些查询。
阅读本教程关于MySQL transaction
的内容答案 1 :(得分:2)
是的,事务允许您执行一系列查询,并在最后提交所有这些更改,或者在其中一个查询失败时将其回滚。
如果您使用的是PDO,基本设置如下:
//optional
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try
{
$pdo->beginTransaction();
$stmt = $pdo->prepare();
$pdo->query();
//in short, all your queries here
$pdo->commit();//commit changes to DB
}
catch (PDOException $e)
{
$pdo->rollBack();//Nothing is changed in DB
}
当然,事务在事务安全存储引擎(InnoDB,BerkeleyDB,ndbcluster)上运行得最好。从MySQL 5开始,事务做在MyISAM上工作,但为了使它们成为原子,因此可以安全使用,你必须自己锁定和解锁表。
见the mysql docs for more details
答案 2 :(得分:0)
交易最适合回滚状态。 ifthats不可能在带有insert的语句前面加上它,它应该让你知道任何错误
答案 3 :(得分:0)
以下是使用mysqli支持我的评论的示例:
if (isset($_POST) && isset($_POST['whatever']))
{
$con = new mysqli("localhost", "user", "pw", "db");
// begin transaction by setting autocommit to false;
$con->autocommit(FALSE);
$stmt = $con->prepare("INSERT INTO `something` (`data`) VALUES (?)");
$stmt->bind_param("s", $_POST['whatever']);
$stmt->execute();
if (!$stmt)
{
$con->rollback();
}
else
{
$con->commit();
}
$stmt->close();
}
你应该知道交易需要innodb表。它有助于检查规格: http://dev.mysql.com/doc/refman/5.0/en/commit.html
有关详细信息,请参阅barranka的评论