我想对生产数据库运行更新查询,作为优秀的小开发人员,我试图尽可能安全。我期待以下
BEGIN TRANSACTION
UPDATE table_x SET col_y = 'some_value'
.
.
.
IF (@@error <> 0)
BEGIN
ROLLBACK
END
ELSE
BEGIN
COMMIT
END
以上内容应该适用于SQL Server,但我需要这个来处理MySQL数据库。
编辑: 抱歉,要执行的语句不止一个。是的我知道不需要在事务中包装单个查询。
答案 0 :(得分:1)
CREATE PROCEDURE prc_test()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
START TRANSACTION;
INSERT
INTO t_test VALUES ('test', 'test');
INSERT
INTO no_such_table
VALUES ('no');
COMMIT;
END;
CALL prc_test();
SELECT *
FROM t_test;
0 rows fetched.
答案 1 :(得分:0)
我不认为这是必要的,因为存在隐式提交/回滚的概念。
来自MySQL docs:
默认情况下,MySQL启动会话 对于每个新连接 启用自动提交模式,所以MySQL确实如此 每个SQL语句之后的提交if 那句话没有回复 错误。如果一个语句返回一个 错误,提交或回滚行为 取决于错误。见章节 13.6.13,“InnoDB错误处理”。
答案 2 :(得分:0)
BEGIN;
UPDATE foo SET bar = 3;
UPDATE bar SET thing = 5;
COMMIT;
如果发生错误,整个事务将自动回滚。如果应用程序中的某些内容表明需要回滚,则实际上只需要执行ROLLBACK
。
可以在MySQL中的过程或复合语句中显式处理错误,但我不建议沿着这条路线走下去。见how-to article和docs for DECLARE HANDLER。您还必须find the specific error code you want to handle,或者您可以使用常规SQLEXCEPTION
条件。您还需要查看compound statements和defining stored programs。
无论如何,根据文档,您可以执行类似下面的查询,但它真的不会做任何不同于我上面的回答。它还可以让任何使用MySQL(包括我自己)的人看到非常奇怪的外观。
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
UPDATE foo SET bar = 3;
UPDATE bar SET thing = 5;
COMMIT;
END;
旧答案:
如果您正在执行单个查询,则这没有意义。只需执行查询;如果发生错误,则不会发生任何事情 - 您的交易将自动回滚。
原因是,默认情况下,所有单个查询都包含在“隐藏”事务中,在MySQL中称为“自动提交”模式。典型的替代方法是明确使用事务 - 一旦执行“BEGIN”,您就开始了事务。一旦您执行COMMIT或ROLLBACK,您将返回自动提交模式。
因此,在MySQL中使用事务的唯一原因是,如果您希望在发生错误(或某些其他外部事件)时回滚到特定状态。在MySQL中,如果发生错误,事务总是被中止。
最后,可以完全关闭此行为,然后您必须始终明确使用事务。我相信当您上次提交或回滚时,暗示“BEGIN”,但您必须COMMIT或ROLLBACK您运行的任何查询。
有关详细信息,请参阅MySQL手册中的The InnoDB Transaction Model。