Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在事务中包装mysql存储函数_Mysql_Function_Transactions - Fatal编程技术网

如何在事务中包装mysql存储函数

如何在事务中包装mysql存储函数,mysql,function,transactions,Mysql,Function,Transactions,return语句是隐式提交吗 您应该如何确保某个函数作为事务运行 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 allo

return语句是隐式提交吗

您应该如何确保某个函数作为事务运行

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 ;
将其包装在事务中

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 ;
在函数内部启动事务并提交

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

此外,我还研究了这个问题,发现一些信息表明:存储函数中的语句不能保证按照声明的顺序执行,这可能会导致二进制日志记录和隐式复制不一致。

我以前不得不使用它,它对我起到了作用:

选择1

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

选择2 要对一系列语句隐式禁用自动提交模式,请使用START TRANSACTION语句:

SET autocommit = {0 | 1}
我从mysql网站上得到了这个-


对于您的情况,如果您查看上面的描述,我认为在函数开始事务之前将autocommit设置为false也是一样的。这样,在事务期间,您的函数不会自动提交。

您的意思是如何避免隐式提交?通过删除commit;,可以避免显式提交;。不,标题有一个有趣的措辞,我无法重新措辞。我想问的是,如果我需要函数内部的提交,但这是不允许的,那么实现相同目标的规范/推荐方法是什么。。。意思是整个函数调用和后续函数调用在事务中运行?我知道删除提交将使代码有效,并且不会出现错误,但是如果我的启动事务没有提交,它会在返回时自动提交吗?如果我选择更新,它会在函数结束后释放行吗?如果没有,我什么时候在函数外调用commit?我已经更新了问题名称,现在可能更清楚了;选择my_功能;犯罪或者我使用SET autocommit=0;内部的功能代码和提交;功能代码之外?是的,从文档和我的经验来看,这似乎是正确的。我没有完全做到这一点,但似乎是正确的。关于另一个问题,不可靠的二进制日志记录行为。这会影响事务安全吗?顺便说一句,既然函数中允许启动事务,为什么不使用它来启动事务,而不是设置自动提交…?要检查自动提交,请选择@@autocommit。
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;