我使用MySQL已经很多年了,但是没有很多使用InnoDB引擎的经验。
我现在正在对它进行一些测试,因为我将要使用它&从我所读到的内容来看,如果THAT交易中的任何查询存在任何问题,则不应该允许任何“通过”。
我的问题是,为什么,在下面的代码....当第三个查询显然有问题时,它仍然将前两个查询输入数据库吗?
$query = "BEGIN";
mysql_query($query);
$query = "INSERT INTO list_columns(lid,column_name) VALUES(8,'test')";
mysql_query($query);
$query = "INSERT INTO list_columns(lid,column_name) VALUES(8,'test')";
mysql_query($query);
$query = "INSERT INT list_columns(lid,column_name) VALUES(8,'test')";
mysql_query($query);
$query = "COMMIT";
mysql_query($query);
修改我了解使用ROLLBACK&所有.....但我认为事务的整个目的是这样的,如果事务中的任何查询都有任何问题,那么它们中的任何一个都将被执行......或者只有多个插入的情况例如,在一个查询中....如果其中一个插入存在问题,那么将不插入任何一个?
答案 0 :(得分:10)
如果问题类似于“此插件违反了唯一键”,则会进行提交。您必须检查自己查询是否返回错误,如果是,则ROLLBACK
。
如果问题是例如意外关闭服务器,则不会发生查询1和2.
当然,由于你的3个查询是相同的,这是一个愚蠢的例子。 Atleast更改lid
以查看。你为什么不做快速测试?
事务的目的确实是以使数据库保持一致状态(在ACID上阅读),但由程序员决定什么是一致的。查看prodigitalson's answer以查看可能的错误捕获方式的示例,为您执行此操作。但是当您处于事务中时,其他进程将无法看到您的事务正在进行的更改 - 因此是原子的和隔离的。
CREATE TABLE `testkeys` (
`lid` INT,
`column_name` VARCHAR(50),
UNIQUE KEY `testuniq` (`lid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
BEGIN;
INSERT INTO testkeys(lid,column_name) VALUES(1,'test 1');
INSERT INTO testkeys(lid,column_name) VALUES(2,'test 2');
INSERT INTO testkeys(lid,column_name) VALUES(3,'test 3');
INSERT INTO testkeys(lid,column_name) VALUES(2,'test 2b');
COMMIT;
答案 1 :(得分:7)
添加Konerak所说的内容......这是一个简化的流程,例如PDO代替mysql
:
$pdo = new PDO($mysqldsn, $user, $pass);
$pdo->beginTransaction();
try {
$pdo->query("INSERT INTO list_columns(lid,column_name) VALUES(8,'test')");
$pdo->query("INSERT INTO list_columns(lid,column_name) VALUES(8,'test')");
$pdo->query("INSERT INT list_columns(lid,column_name) VALUES(8,'test')");
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollBack();
throw $e;
}
答案 2 :(得分:1)
您需要手动检查它,如果有任何错误,您需要自己回滚它。
答案 3 :(得分:0)
当您通过php执行sql查询时,它不会像单个mysql命令那样工作。 为了使上述事务正常进行,您需要在try catch块中包装代码,并设置mysql_autocommit为关闭状态,运行insert query并使用mysql_commit提交成功的工作,或者在catch块中使用mysql_rollback,以防出现任何错误。
$con=mysqli_connect("localhost","my_user","my_password","my_db");
try{
mysqli_autocommit($con,FALSE);
$query = "INSERT INTO list_columns(lid,column_name) VALUES(8,'test')";
mysql_query($query);
$query = "INSERT INTO list_columns(lid,column_name) VALUES(8,'test')";
mysql_query($query);
$query = "INSERT INT list_columns(lid,column_name) VALUES(8,'test')";
mysql_query($query);
mysql_commit($con);
}catch{
mysql_rollback($con);
}