2012-06-05 6 views
2
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 ; 

Являются ли заявления возврата подразумеваемыми?Как обернуть хранимую функцию mysql в транзакции

Как вы должны обеспечить выполнение определенной функции как транзакции?

Оберните его сделкой?

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

Запустить транзакцию внутри функции и совершить?

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

Также я уже исследовал этот вопрос и нашел некоторую информацию, что сказал что-то вдоль линий: «заявления в хранимых функций не гарантируется выполняться в заявленном порядке, который может сделать бинарный лог (и неявно репликации) непоследовательным ".

+0

Вы имеете в виду «Как избежать _implicit_ commit?» Вы можете избежать _explicit_ commit, удалив «commit;». – Ben

+0

Нет, название имеет смешную формулировку, которую я не мог перефразировать. Я спрашиваю, **, если мне нужна фиксация внутри функции, но это недопустимо, каков канонический/рекомендуемый способ достижения той же цели ... что означает весь вызов функции и последующие вызовы функций, выполняемые внутри транзакция? ** –

+0

Я знаю, что сброс COMMIT сделает код действительным, и никаких ошибок не возникнет, но если у меня есть START TRANSACTION без фиксации, он будет автокомментировать по возвращении? Если I SELECT FOR UPDATE будет освобождать строки после окончания функции? Если нет, то когда я вызываю commit вне функции? –

ответ

1

я должен был использовать это раньше, и он работал на меня:

Вариант 1

SET autocommit = {0 | 1} 

После завершения то, что вы хотите сделать, вы можете включить его или вызовите явная фиксация.

Вариант 2 Чтобы отключить режим автоматической фиксации неявно для одной серии заявлений, используйте START TRANSACTION заявление:

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

Я получил это от самого тузда сайта - MySQL


Для вашей ситуации я бы подумал, что установка autocommit на false до того, как функция выполнит трюк (запуск транзакции - это то же самое, если вы посмотрите на de сценарий этого выше). Таким образом, во время транзакции ваша функция не автокомпрометирует.

+0

Так что в основном я либо выхожу «START TRANSACTION», «SELECT my_function();« COMMIT; », либо я использую' SET autocommit = 0; 'внутри кода функции и' COMMIT; 'вне кода функции? –

+0

Да, насколько я могу судить по документации и моему опыту, это кажется правильным. Я не сделал этого точно, но кажется правильным. – hbhakhra

+0

И про другой вопрос, ненадежное поведение двоичного журнала. Это влияет на безопасность транзакций? –

Смежные вопросы