即使发生错误,也会提交MySQL事务

时间:2013-07-01 10:44:50

标签: php mysql transactions

在我的项目中,我删除并更新了许多表中的大量行,因此我决定使用事务。但是,当发生错误并且脚本结束时,事务甚至会被提交。

我只使用 mysql _ 而不是 mysqli _ PDO ,因为在该服务器上它不受支持。

mysql_query("START TRANSACTION");
$res = mysql_query("some insert...");
if($res === false){
  //this save error log and exit script with die() or exit()
  trigger_error(mysql_errno()."\n".mysql_error()); 
}
$res = mysql_query("some delete...");
if($res === false){
  trigger_error(mysql_errno()."\n".mysql_error()); 
}
mysql_query("COMMIT");

在我的项目中,我的mysql是我的类,所以我不要这样输入,但这样就可以了。

发生第一次查询错误后,保存错误日志结束脚本结束。但插入的数据保留在DB中。但是,当COMMIT未执行且连接已关闭时,会自动ROLLBACK发生。

P.S。我知道,使用mysqli应该会更好,但这对于 mysql _ mysqli _ 是一样的,不是吗?

2 个答案:

答案 0 :(得分:1)

我建议阅读:http://dev.mysql.com/doc/refman/5.0/en/commit.html,特别是 SET autocommit = 0 。我相信,如果你不想自动提交,你需要说出来,然后才会自动提交 ROLLBACK 你的陈述。

最好有一个处理程序代码来调用 ROLLBACK ,否则你有信任MySQL为你做所有工作的危险,以及任何与TRANSACTIONS相关的MySQL未来的任何变化都可能你的代码没有妥善处理。

答案 1 :(得分:1)

您确定数据是否保留在数据库中/是否在未执行提交查询的情况下提交?

MySQL documentation

  

要为一系列语句隐式禁用自动提交模式,请使用START TRANSACTION语句:

     

START TRANSACTION;

     

SELECT @A:= SUM(薪水)FROM table1 WHERE type = 1;

     

UPDATE table2 SET summary = @ WHERE type = 1;

     

COMMIT;

     

使用START TRANSACTION,自动提交将保持禁用状态,直到您使用COMMIT或ROLLBACK结束事务。然后,自动提交模式将恢复为先前的状态。

我使用MySQL 5.5和PHP 5.3测试了这段代码:

sql> create table t10 (id integer auto_increment primary key, status char(32))

<?php

  if( ($link = mysql_connect("localhost", "db_user", "*****")) === false )
    exit(1);

  mysql_select_db("test", $link);

  var_dump(mysql_query("start transaction;"));
  var_dump(mysql_query("insert into t10 (status) values (\"foo1\"), (\"foo2\");"));
  exit();
  //var_dump(mysql_query("commit;"));
  var_dump(mysql_close());
?>

值foo1和foo2未插入数据库表t10中。还要记住,MySQL事务在“全有或全无”规则的意义上并不是完全原子的。您可以使用一半的语句提交事务,另一半则失败(来源:Kouber Saparev于2010年12月3日上午11:01在MySQL页面http://dev.mysql.com/doc/refman/5.5/en/ansi-diff-transactions.html)。

测试用例:

mysql> create table t7 (id integer primary key auto_increment, name text, lastname text);
Query OK, 0 rows affected (0.04 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t7 (name, lastname) values('name1', 'lastname1');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t7 (name, lastname) values('name1', 'lastname1');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t7 (name, lastname) ('name1', 'lastname1');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near ''name
1', 'lastname1')' at line 1
mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from t7;
+----+-------+-----------+
| id | name  | lastname  |
+----+-------+-----------+
|  1 | name1 | lastname1 |
|  2 | name1 | lastname1 |
+----+-------+-----------+
2 rows in set (0.00 sec)

我们发现即使事务已成功提交,插入查询失败也不算数。