3
DROP FUNCTION IF EXISTS my_func;
DELIMITER ||
CREATE FUNCTION my_func(arg_id INT) RETURNS VARCHAR(200)
BEGIN
    DECLARE local_id INT;
    DECLARE local_name VARCHAR(200);
    START TRANSACTION; /* <-- this is allowed */
        SELECT      id, name
            INTO    local_id, local_name
            FROM    table
            WHERE   id = arg_id
            FOR UPDATE;
        SELECT my_other_function(local_name) INTO local_name;
        UPDATE table SET name = local_name;
    COMMIT; /* <-- this is not allowed
        and yields an "Explicit or
        implicit commit is not
        allowed..." error */
    RETURN local_name;
END||
DELIMITER ;

return 语句是隐式提交吗?

您应该如何确保某个功能作为事务运行?

将其包装在交易中?

START TRANSACTION;
    SELECT my_func(33); /* <-- no transaction statements inside the function */
COMMIT;

在函数内部启动事务并提交?

SELECT my_func(33); /* <-- contains only the START TRANSACTION line */
COMMIT;

此外,我研究了这个问题,发现一些信息类似于以下内容:“存储函数中的语句不能保证以声明的顺序执行,这可能会使二进制日志记录(和隐式复制)不一致”。

4

1 回答 1

2

我以前必须使用它,它对我有用:

选项1

SET autocommit = {0 | 1}

完成您想做的事情后,您可以重新启用它或调用显式提交。

选项 2 要为单个语句系列隐式禁用自动提交模式,请使用 START TRANSACTION 语句:

START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

我从 mysql 网站本身得到这个 - MySQL


对于您的情况,我认为在函数之前将 autocommit 设置为 false 可以解决问题(如果您查看上面的描述,启动事务是同样的事情)。这样,在交易期间,您的功能不会自动提交。

于 2012-06-05T13:11:21.133 回答