在MariaDB中的条件下回滚

时间:2017-11-13 19:26:01

标签: sql transactions mariadb

我有一个交易,用循环中的金额减少变量,如果有钱的变量低于0,金额应该返回到交易前的值。在这种情况下,如何在MariaDB中适当地使用回滚?

---修改

我有类似的东西,它不起作用,查看if(budget<0)中的行,因为如果钱低于0而某些,但不是全部,迭代被制作并保存到temp表,表格显示了它们

BEGIN
    DECLARE temppesel text;
    DECLARE tempsalary int;
    DECLARE budget int DEFAULT cash;
    DECLARE done bool DEFAULT false;
    DECLARE occ CURSOR FOR (SELECT pesel, pensja FROM pracownicy where zawod=occupation);
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true;

    START TRANSACTION;
        DROP TABLE IF EXISTS temp;
        CREATE TABLE temp ( Result text );
        OPEN occ;
            occ : LOOP
                FETCH occ INTO temppesel, tempsalary;
                SET budget = budget - tempsalary;

                IF(done) THEN
                    LEAVE occ;
                END IF;

                IF(budget<0) THEN
                    ROLLBACK;
                    LEAVE occ;                      
                END IF;

                INSERT INTO temp VALUES (concat('********',substr(temppesel,9,3), ', wyplacono')); 
            END LOOP;
        CLOSE occ;

        SELECT * FROM temp;
        DROP TABLE temp;
    COMMIT;
END

2 个答案:

答案 0 :(得分:1)

BEGIN;
do some SQL
Loop:
    do some SQL
    if something is wrong, ROLLBACK and exit the loop and transaction
    do some SQL
if something, go back to Loop
do some SQL
COMMIT;

也就是说,让ROLLBACK撤消所有,因为BEGIN

更多

现在SP可见了......

  • temp是什么引擎?如果它是MyISAM,那么它不会回滚。 SHOW VARIABLES LIKE 'default_storage_engine';
  • 请不要将occ用于两件不同的事情,这会让读者感到困惑。
  • 在预算爆炸时,您是否希望输出成为pracownicy行的一部分?或者你想要没有行?
  • 如果您有多个连接执行相同的操作,则存在严重问题 - 所有连接都可以看到temp,并且它们可以相互踩踏。更改为CREATE TEMPORARY TABLE temp ...
  • 但是,通过预测试(下方),您可以完全避免使用temp。首先测试它的需要,然后(如果需要)只为所有行做一个SELECT
  • 如果你什么都不想要,那么这样的简单测试会预先测试它是否会溢出,从而避免了在循环中进行测试的需要:

...

IF ( SELECT  SUM(pensja)
    FROM  pracownicy
    where  zawod=occupation ) > budget )

答案 1 :(得分:1)

我认为CREATE TABLE语句导致事务被提交。 Here是导致隐式COMMIT的命令列表。

如前面提到的链接所述,您可以在START TRANSACTIONDROP命令之后移动CREATE语句,或使用CREATE TEMPORARY TABLE语法创建临时表:< / p>

CREATE TEMPORARY TABLE temp ( Result text );