数据库mysql:处理事务嵌套存储过程中的回滚

bprjcwpo  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(466)

我有4个存储过程,让我们把它们命名为spa、spb、spc和spd。
每个存储过程都有一个启动事务、提交和回滚。
spa当前是父存储过程(sp),在它内部,我按各自的顺序调用spb、spc、spd。显然,由于所有SP中都有提交,因此当spc失败时,在spb中执行的dml操作不会恢复为已提交的操作,而在spd失败时,spb和spc中的操作不会回滚。
我在spb、spc和spd中使用commit的原因是,稍后,我可能会直接使用这些sp中的任何一个来执行与该sp相关的操作。
目前,我计划使用输入位标志来决定是否提交事务。在ms sql中,有一个选项可以检查@@transcount,但是我在mysql中找不到类似的内容。
我想知道是否有更好的方法来处理这种情况。

n3ipq98p

n3ipq98p1#

管理你自己的变量看起来mysql不能处理这种行为。因此,添加一个输入p\u tran\u call位并将其设置为1,如果spa调用else 0,则执行该操作,如果p\u tran\u call为0,则开始tran并回滚。
当然,我就是这样做的。
创建过程spb(p\u tran\u control bit)为

declare exit handler for sqlexception
   begin
         if p_tran_control = 0 the 
             rollback;
         end if;
   end; #end of handler

  if p_tran_control = 0 then
         begin transaction;
   end if;

    #more code;

   if p_tran_control = 0 then
        commit;
    end if;

结束
创建过程spa开始

begin transaction;

 call spB(1);

  commit transaction;

结束
现在,我注意到,这些事务不会转到任何嵌套调用。因此,如果您从spa调用spb,那么spc工作,但是如果您从spb调用spc,那么spc将提交,spa从spa调用spc,而spa持有事务。即使“自动提交”设置为“关闭”;

nqwrtyyt

nqwrtyyt2#

我同意上述评论。我建议在调用任何存储过程之前,只在应用程序的“顶层”启动并提交事务。不要在存储过程中开始或提交事务。
尝试像microsoft sql server那样欺骗回滚和提交 @@trancount 导致了比上面的指导方针更难处理的异常情况,以便在应用程序级别管理事务。
10年前我发布了一个类似的答案,但它与orm类有关,而不是与存储过程有关:如何检测事务已经启动?

相关问题