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;
また、この問題を調査したところ、「格納された関数のステートメントが宣言された順序で実行されることが保証されていないため、バイナリロギング(および暗黙的にレプリケーション)が不整合になる可能性がある」という情報が見つかりました。