2017-11-13 9 views
0

돈이있는 변수가 0보다 작 으면 트랜잭션의 금액으로 변수를 줄이는 트랜잭션이 있습니다. 트랜잭션이 발생하기 전에 금액이 반환되어야합니다. 이 경우 MariaDB에서 롤백을 적절하게 사용하려면 어떻게해야합니까?MariaDB에서 조건부 롤백

--- 편집은

나는 그런 일이 있고, 그들 모두를 작동 돈이 0과 일부 미만이면 때문에 if(budget<0)의 라인을 체크 아웃,하지만하지 않습니다, 반복이 만들어졌다 그리고 임시 테이블에 저장, 테이블이 그들에게있다

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 

답변

1

I를 : 그것은, therey 루프에서 테스트를위한 필요성을 제거 오버 플로우 여부

  • 는 아무것도하지 않으려면, 다음과 같은 간단한 테스트 뭔가 것이다 사전 테스트 CREATE TABLE 문으로 인해 트랜잭션이 커밋되었다고 생각하십시오. Here은 암시적인 COMMIT을 야기하는 명령 목록입니다. 상기 링크 설명으로

    , 당신은 DROPCREATE 명령 후 START TRANSACTION 문을 이동하거나 임시 테이블을 만들 수 CREATE TEMPORARY TABLE 구문을 사용할 수 있습니다 : 나는 개선 후 내 코드를 게시

    CREATE TEMPORARY TABLE temp (Result text); 
    
  • +0

    방금 ​​DROP을 제거하고 TEMPORARY를 테이블 temp에 추가하면 작동합니다. – jakub1998

    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; 
    

    를 보여줍니다 ROLLBACKBEGIN 이후 모든을 취소 할 수 있습니다. 이제 SP가 표시되어있는

    ...

    • temp은 무엇 엔진

      ? MyISAM이면 롤백되지 않습니다. SHOW VARIABLES LIKE 'default_storage_engine';.
    • 두 가지 다른 용도로 occ을 사용하지 마십시오. 독자를 혼동시킵니다.
    • 예산이 날 때 출력이 pracownicy 행의 일부가되도록 하시겠습니까? 또는 행을 행으로 하시겠습니까?
    • 같은 일을하는 연결이 여러 개있는 경우 심각한 문제가 있습니다. temp은 모든 연결에서 볼 수 있으며 서로 밟을 수 있습니다. CREATE TEMPORARY TABLE temp ...
    • 으로 변경하십시오. 그러나 사전 테스트 (아래)를 사용하면 temp의 사용을 완전히 피할 수 있습니다. 필요한 경우 첫 번째 테스트를 수행 한 다음 (필요한 경우) 모든 행에 대해 단일 을 수행하면됩니다. ..

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

    을, 나는 그것을 생각 코드에서와 다른 방식으로 수행되어야합니다. 어떻게하면 더해야합니까? – jakub1998

    +0

    @ jakub1998 - 답변에 "more"를 추가했습니다. –