3

重複の可能性:
ネストされたトランザクションは MySQL で許可されていますか?

トランザクションを使用するストアド プロシージャがあり、トランザクション内でトランザクションを使用してテーブルを更新する別のプロシージャを呼び出します。2 番目のプロシージャはループ内で呼び出され、呼び出しごとに 1 つの行が更新されます。この 2 番目の手順では、一時テーブルも作成されます。エンジンは、永続テーブルの場合は InnoDB、一時テーブルの場合は MyISAM です。MySQL のバージョンは 5.5.16 です。

私が望むのは、エラーが発生した場合に、2 番目の手順によって行われたすべての更新をロールバックすることです。

これは可能ですか?私は、DDL ステートメントとトランザクションの開始を知っています。コミットを発行しますが、それを回避する方法はありますか?

コードは次のようになります: (ロールバックは明らかに機能しません)

delimiter $$
drop procedure if exists `proc1`$$
create procedure `proc1`( 
  ...#some variables
) 
modifies sql data

begin
    declare error int default 0;
    declare continue handler for sqlexception
    begin 
        set error=1;
    end;


     drop temporary table if exists table1;
     create temporary table table1 (

         id int unsigned, 
         col1 decimal(12,6) default 0, 
         col2 decimal (12,6) default 0, 
         col3 decimal (12,6),

         primary key (id)) engine=MyISAM;

     START TRANSACTION;
        begin
           declare id_1 int unsigned;
           declare v1 decimal(12,6) default 0;
           declare v2 decimal(12,6) default 0;
           declare v3 decimal(12,6) default 0;

           declare done int default 0;

          declare cur cursor for select id, col1, col2 from table1;
          declare continue handler for not found set done=1;

          begin
              open cur; 
              wh: while done=0 do
                  fetch cur into id, v1, v2;
                   if done=1 then
                          leave wh;
                   end if;

                   set v3=v1+v2 ;                                      
                   update table1 set col3=v3 where id =id_1;

                   CALL  proc2(id_1, v1, v2, v3);

                   end while wh;
                   close cur;
                   set done=0;
                 end;

            end;
           if error=0 then
                  commit;
                  set status=1;

            else 
                  rollback;
                 set status=-1;
            end if;


end$$
4

1 に答える 1

6

一度に開くことができるトランザクションは 1 つだけです。既存のトランザクションが既に存在するときに新しいトランザクションを開始しようとすると、既存のトランザクションがコミットされます。ただし、 savepointsを使用してネストされたトランザクションをエミュレートできます。

于 2012-09-22T11:03:17.660 に答える