MySQL存储过程、事务和回滚

13

我找不到在MySql存储过程中使用事务的最佳方法。如果出现任何问题,我想要ROLLBACK

BEGIN

    SET autocommit=0;
    START TRANSACTION;

    DELETE FROM customers;
    INSERT INTO customers VALUES(100);
    INSERT INTO customers VALUES('wrong type');

    COMMIT;
END

1)需要使用autocommit=0吗?

2)如果第二个INSERT出现错误(当然会出错),第一个INSERT不会回滚。程序仅仅继续执行到COMMIT。如何防止这种情况发生?

3)我发现可以DECLARE HANDLER,我应该使用这个指令还是有更简单的方法来表示,如果任何命令失败,存储过程应该ROLLBACK并且也失败?

DECLARE HANDLER工作得很好,但由于我使用的是MySql 5.1版本,无法使用RESIGNAL。因此,如果出现错误,调用者将不会收到通知:

DECLARE EXIT HANDLER FOR SQLEXCEPTION 
BEGIN
    ROLLBACK; 
    -- RESIGNAL; not in my version :(
END;

START TRANSACTION;
2个回答

12

回答1:你不需要设置autocommit=0

使用START TRANSACTION时,只有在使用COMMIT或ROLLBACK结束事务之前,autocommit才会保持禁用状态,之后autocommit模式将恢复到以前的状态。

http://dev.mysql.com/doc/refman/5.6/en/commit.html


该页面上的另一条语句是:“要隐式禁用单个语句系列的自动提交模式,请使用START TRANSACTION语句”。 - Will B.

1

回答2的不同方法:您可以使用布尔变量来确定是应该提交还是回滚。例如:

BEGIN

DECLARE `should_rollback` BOOL DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `should_rollback` = TRUE;

START TRANSACTION;

DELETE FROM customers;
INSERT INTO customers VALUES(100);
INSERT INTO customers VALUES('wrong type');

IF `should_rollback` THEN
    ROLLBACK;
ELSE
    COMMIT;
END IF;
END

或者,你可以使用非常有用的 3)。

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