如何在php/mysql中使用事务?

9

我正在使用PHP/MySQL。我知道MySQL中的事务,但无法在我的脚本中使用。以下是我的脚本,如何在代码中使用PHP事务,即BEGIN、ROLLBACK和COMMIT。

foreach($json_a['shop'] as $jsondata=>$json)
{
if($json['category']==='product')
{
$name_product=$json['name'];
$query1="insert into product(id,name,user_id)values('','" . mysql_real_escape_string($name_product). "','1')";

$result1=mysql_query($query1) or die("error in query".mysql_errno());
//echo "success...!";
$product++;
}
else
if($json['category']==='order')
{
$name_order=$json['name'];
$query2="insert into order(id,name,user_id)values('','" . mysql_real_escape_string($name_order). "','1')";

$result2=mysql_query($query2) or die("error in query".mysql_errno());
$order++;
}
else
if($json['category']==='sale')
{
$name_sale=$json['name'];
$query3="insert into sale(id,name,user_id)values('','" . mysql_real_escape_string($name_sale). "','1')";

$result3=mysql_query($query3) or die("error in query".mysql_errno());
$sale++;
}
}

你可以通过在正确的位置使用它们来使用它们吗?请问您能澄清一下您的问题吗?很难理解您的意思。 - Charles
我在询问有关事务的问题,我的目的是有时第一个查询被执行并且数据被插入到数据库中,但第二个查询没有正确执行,因此我想回滚事务,以便插入顺序不会被破坏。 - hunter
3个回答

14

只需发出mysql_query('START TRANSACTION');并在每个插入操作时检查错误。如果其中一个不成功,立即发出ROLLBACK而不执行任何剩余的查询。如果所有操作都正常完成,则发出COMMIT。

为避免使用过多的if-else嵌套,请将它们放入try-catch块中可能更容易些。

// START TRANSACTION
try{
    // INSERT 1
    if(failed)
        throw new Exception();

    // INSERT 2
    if(failed)
        throw new Exception();

    // INSERT 3
    if(failed)
        throw new Exception();

    // COMMIT
}
catch(Exception $e){
    // ROLLBACK
}

您可能还想查看一下PHP的PDO扩展。事务是其功能的一部分。


+1 这很棒,是如何理想地构建这个结构的简洁表述。 - philwinkle
我嵌套了查询,只是因为它是foreach循环的一部分,请看我的更新问题。 - hunter
@hunter 无论你有什么,你都可以使用这种策略。只需用 try 包装所有内容,当你决定需要回滚时就抛出异常即可。请注意,在你的情况下,两次插入不可能在同一次运行中执行,所以实际上并不需要事务。你计划添加其他查询吗? - Alin Purcaru
捕获代码应该是 catch(Exception $e){,而不是上面的另一种方式。 - Sphinx
@Sphinx 棒极了。谢谢! - Alin Purcaru
显示剩余3条评论

5

一种选择是使用PDO。示例:

$db = new PDO($dsn,$user,$password);

$db->beginTransaction();
$db->exec("delete from mytable");

$allGood = doSomethingElse();

if ($allGood)
{
  $db->commit();
} else {
  $db->rollBack();
}

或者更优雅的方法:
$db = new PDO($dsn,$user,$password);
$db->beginTransaction();

try{
  //first execution      
  $db->exec("delete from mytable");

  //second execution
  $db->exec("insert into anothertable");

  //if all went well
  $db->commit();

} catch (Exception $e) {

  //something broke, hit undo
  $db->rollBack();

}

2

在这里,与常规MySQL语句相同,关于事务的规则/语法也适用。

以下是一个例子:

$query0 = 'START TRANSACTION;';
mysql_query($query0) or die('woops' . mysql_error());

/* all of your queries here */

$query5 = 'COMMIT;';
mysql_query($query5) or die('woops' . mysql_error());

你可以在这里找到有关MySQL事务语法的更多信息:http://dev.mysql.com/doc/refman/5.0/en/commit.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接