【问题标题】:ERROR 1305 (42000): SAVEPOINT ... does not exist错误 1305 (42000): SAVEPOINT ... 不存在
【发布时间】:2013-11-09 07:24:52
【问题描述】:

我的 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');

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

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

【问题讨论】:

    标签: mysql savepoints


    【解决方案1】:

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

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

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

    【讨论】:

    • 很好的提示。在我的情况下,DROP TEMPORARY TABLE 更改为 DROP TABLE。非常有用的链接。谢谢。
    【解决方案2】:

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

    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 ;
    

    【讨论】:

      【解决方案3】:

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

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

      注意

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

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

      【讨论】:

        猜你喜欢
        • 2012-10-21
        • 1970-01-01
        • 2014-08-17
        • 1970-01-01
        • 2019-06-06
        • 2014-04-20
        • 2021-08-15
        • 1970-01-01
        • 2016-11-28
        相关资源
        最近更新 更多