MySQL - 如何使函数原子化?

时间:2011-06-27 16:55:57

标签: mysql database

我的数据库中有这个功能

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-else语句的if部分中,我想以原子方式执行所有操作。 我想使用START TRANSACTION命令,但它们在函数中是不允许的,我找不到任何其他命令来执行它。

默认情况下函数是原子的吗? 如果没有,有什么办法可以实现吗?

谢谢, 奥斯卡

编辑:如果我必须使用某个功能,是否可以进行交易?

1 个答案:

答案 0 :(得分:0)

使用带有输出参数的存储过程来返回操作状态。

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构造启动,提交或回滚事务。

修改 交易需要使用InnoDB引擎,因为@bobobobo会在评论中注明。