我想对一个生产数据库运行一个更新查询,作为一个优秀的小开发人员,我正试图使它尽可能安全。我希望做到以下几点
BEGIN TRANSACTION
UPDATE table_x SET col_y = 'some_value'
.
.
.
IF (@@error <> 0)
BEGIN
ROLLBACK
END
ELSE
BEGIN
COMMIT
END上面的代码应该可以在SQL Server中运行,但我需要在MySQL数据库中使用它。
EDIT:对不起,有多条语句要执行。是的,我知道不需要在一个事务中包装单个查询。
发布于 2009-02-16 09:01:45
我不认为这是必要的,因为有隐式提交/回滚的概念。
来自MySQL docs:
默认情况下,MySQL在启用自动提交模式的情况下为每个新连接启动会话,因此如果每个
语句没有返回错误,MySQL将在该语句之后执行commit。如果语句返回错误,则提交或回滚行为取决于错误。请参阅第13.6.13节“InnoDB错误处理”。
发布于 2009-02-16 09:02:29
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“,就已经启动了一个事务。一旦您提交或回滚,您将返回到自动提交模式。
因此,在MySQL中使用事务的唯一原因是希望在发生错误(或其他外部事件)时回滚到特定状态。在MySQL中,如果出现错误,事务总是会中止。
最后,完全关闭此行为是可能的,然后必须始终显式使用事务。我相信"BEGIN“是在您上次提交或回滚时暗示的,但您必须提交或回滚您运行的任何查询。
有关更多信息,请参阅MySQL手册中的The InnoDB Transaction Model。
发布于 2009-02-16 09:50:46
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.https://stackoverflow.com/questions/552628
复制相似问题