MySQL - Как я могу сделать функцию атомарной? - PullRequest
3 голосов
/ 27 июня 2011

У меня есть эта функция в моей БД

CREATE FUNCTION BookBed (pPaciente varchar(255),
                                pHospital bigint(20)) RETURNS BOOLEAN
BEGIN
DECLARE NumLeitosDisponiveis INT;
DECLARE vReservaOK  BOOLEAN;
DECLARE dt TIMESTAMP;

 SET dt = (Select now());
 SET NumLeitosDisponiveis = (SELECT AVAILABLEBEDCOUNT FROM HOSPITAL WHERE ID = pHospital); 


 IF((SELECT NumLeitosDisponiveis) > 0) THEN 
 BEGIN
  START TRANSACTION;

  INSERT INTO RESERVATION(PERSON, HOSPITAL, DATE) VALUES (pPaciente, pHospital, dt);

  UPDATE HOSPITAL
    SET AVAILABLEBEDCOUNT = AVAILABLEBEDCOUNT - 1 
    WHERE ID = pHospital;

    SET vReservaOk = true;

    commit;
 END;
  ELSE 
    SET vReservaOk = false;     
  END IF;


 RETURN vReservaOK;

END;

В части if моего оператора if-else я хотел бы выполнить все операции атомарным способом.Я хотел использовать команду START TRANSACTION, но они не разрешены в функциях, и я не смог найти другую команду для ее выполнения.

Являются ли функции атомарными по умолчанию?Если нет, есть ли способ, которым я могу это реализовать?

Спасибо, Оскар

РЕДАКТИРОВАТЬ: И если я должен использовать функцию, возможно ли иметь транзакции?

1 Ответ

0 голосов
/ 27 июня 2011

Используйте хранимую процедуру с выходным параметром для возврата рабочего состояния.

DELIMITER //

CREATE PROCEDURE BookBed (
    pPaciente varchar(255),
    pHospital bigint(20),
    OUT oReservaOK boolean)
BEGIN
    DECLARE NumLeitosDisponiveis INT;
    DECLARE dt TIMESTAMP;

    SET dt = (Select now());
    SET NumLeitosDisponiveis =
        SELECT AVAILABLEBEDCOUNT FROM HOSPITAL WHERE ID = pHospital; 

    IF((SELECT NumLeitosDisponiveis) > 0) THEN 
    BEGIN
        START TRANSACTION;

        INSERT INTO RESERVATION(PERSON, HOSPITAL, DATE)
            VALUES (pPaciente, pHospital, dt);

        UPDATE HOSPITAL
            SET AVAILABLEBEDCOUNT = AVAILABLEBEDCOUNT - 1 
        WHERE ID = pHospital;

        SET oReservaOk = true;

        commit;
    END;
    ELSE 
        SET oReservaOk = false;     
    END IF;
END//

Если у вас возникли проблемы с вызовом хранимой процедуры с использованием Hibernate, переместите логику транзакции в Hibernate. То есть запустить, зафиксировать или откатить транзакцию с использованием конструкций Hibernate.

EDIT Транзакции требуют использования движка InnoDB, как @bobobobo отмечает в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...