4

我的 MYSQL DB 中有这个 SQL(sproc 的主体为空,所以我猜没有隐式提交?)。

DROP PROCEDURE IF EXISTS doOrder;

DELIMITER $$

CREATE PROCEDURE doOrder(IN orderUUID VARCHAR(40))
  BEGIN
    SAVEPOINT sp_doOrder;

    BEGIN
      DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK TO sp_doOrder;

      -- doing my updates and selects here...

    END;

    RELEASE SAVEPOINT sp_doOrder;
  END $$

DELIMITER ;

当我

call doOrder('some-unique-id');

我得到:错误 1305 (42000):SAVEPOINT sp_doOrder 不存在。

我可能会忽略一些东西......有什么想法吗?

4

3 回答 3

6

由于这是在 Google 上搜索“保存点不存在”时的最佳答案,因此我也会在此处添加我的解决方案。

TRUNCATE我在事务中执行的代码中有一条语句,这导致了隐式提交并因此结束了事务。在事务之外创建保存点不会导致错误,它只是不会被执行。这意味着当您尝试释放保存点/将其回滚时,您第一次会注意到有问题。

这是导致隐式提交的完整语句列表:https ://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html

于 2018-11-13T16:07:26.570 回答
3

您必须使用 START TRANSACTION 而不是 BEGIN 来启动存储过程中的事务。

此外,您可能需要将 SAVEPOINT 语句移到 DECLARE 之后(取决于您放置 START TRANSACTION 的位置)

笔记

在所有存储程序(存储过程和函数、触发器和事件)中,解析器将 BEGIN [WORK] 视为 BEGIN ... END 块的开始。在此上下文中使用 START TRANSACTION 开始事务。

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

于 2013-10-30T01:37:38.163 回答
1

这最终奏效了。谢谢乌狗。

DROP PROCEDURE IF EXISTS doOrder;

DELIMITER $$

CREATE PROCEDURE doOrder(IN orderUUID VARCHAR(40))
  BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK TO sp_order;

    START TRANSACTION;
    SAVEPOINT sp_order;

    -- doing my updates and selects here...

    COMMIT;

  END $$

DELIMITER ;
于 2013-10-30T11:17:47.297 回答