【问题标题】:MySQL: Procedure calls within a transaction are causing commitsMySQL:事务中的过程调用导致提交
【发布时间】:2017-09-12 11:24:47
【问题描述】:

我有一个调用生成过程的事务,但是如果在该过程之后发生错误,我注意到该过程期间和之前的语句已被提交。流程如下:

DELIMITER $$    
CREATE PROCEDURE location_processor(in _city varchar(20), in _country_code varchar(2), out id int)
    begin
        select location_id into id from location where city = _city and country_code = _country_code limit 0,1;
        if id is null then
            select @id := max(location_id) from location;
            if @id is null then
                set @id = 0;
            end if;
            set @id = @id + 1;
            insert into location (location_id, city, country_code)
            values(@id, _city, _country_code);
            set id = @id;
        end if;
    end; $$
DELIMITER ;

注意:此过程中没有使用开始/结束事务语法;虽然我有理由相信程序本身的开始和结束导致提交:

注意:

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

(https://dev.mysql.com/doc/refman/5.7/en/commit.html)

我需要这个过程来检查错误。有没有办法避免在事务中使用过程时提交?

【问题讨论】:

    标签: mysql stored-procedures transactions


    【解决方案1】:

    举个简单的例子,我无法重现问题:

    mysql> DROP PROCEDURE IF EXISTS `location_processor`;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> DROP TABLE IF EXISTS `location`;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CREATE TABLE IF NOT EXISTS `location` (
        ->     `location_id` INT,
        ->     `city` VARCHAR(255),
        ->     `country_code` VARCHAR(255)
        -> );
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> DELIMITER //
    
    mysql> CREATE PROCEDURE `location_processor`()
        -> BEGIN
        ->     INSERT INTO `location`
        ->         (`location_id`, `city`, `country_code`)
        ->     VALUES
        ->         (2, 'city', 'country_code');
        -> END//
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> DELIMITER ;
    
    mysql> START TRANSACTION;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT `location_id`, `city`, `country_code`
        -> FROM `location`;
    Empty set (0.00 sec)
    
    mysql> INSERT INTO `location`
        ->     (`location_id`, `city`, `country_code`)
        -> VALUES
        ->     (1, 'city', 'country_code');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> CALL `location_processor`;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> INSERT INTO `location`
        ->     (`location_id`, `city`, `country_code`)
        -> VALUES
        ->     (3, 'city', 'country_code');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> SELECT `location_id`, `city`, `country_code`
        -> FROM `location`;
    +-------------+------+--------------+
    | location_id | city | country_code |
    +-------------+------+--------------+
    |           1 | city | country_code |
    |           2 | city | country_code |
    |           3 | city | country_code |
    +-------------+------+--------------+
    3 rows in set (0.00 sec)
    
    mysql> ROLLBACK;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT `location_id`, `city`, `country_code`
        -> FROM `location`;
    Empty set (0.00 sec)
    

    【讨论】:

      猜你喜欢
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 2012-05-22
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      相关资源
      最近更新 更多