我有4个存储过程,让我们将它们命名为spA、spB、spC和spD。
每个存储过程都有一个开始事务、提交和回滚.
当前,procedure(SP)是存储在spA中的父,在其中,我按各自的顺序调用spB、spC、spD。显然,因为所有的SPs都有提交,所以当spC失败时,在spB中执行的DML操作不会恢复,因为它们已经提交了,而当spD失败时,spB和spC中的操作没有回滚。
我在spB、spC和spD中提交的原因是,以后我可能只需直接使用这些SPs中的任何一个来执行与SP相关的操作。
目前,我计划使用输入位标志来决定是否提交事务。在MySQL中,有一个选项可以检查@@transcount,但是,我无法在MySQL中找到类似的内容。
我想知道是否有更好的方法来处理这种情况。
发布于 2018-05-22 14:57:47
我同意上述意见。我建议您在调用任何存储过程之前,只应在应用程序中的“顶级”启动和提交事务。不要在存储过程中开始或提交事务。
试图欺骗回滚和提交,就像Microsoft在@@trancount中所做的那样,会导致比上面的指导方针更难处理的异常,以便在应用程序级别管理事务。
10年前,我发布了类似的答案,但它与ORM类有关,而不是存储过程:How do detect that transaction has already been started?。
发布于 2018-08-28 17:47:34
管理您自己的变量--看起来MySQL不处理这种行为。因此,添加一个输入p_tran_call位,并将其设置为1,如果spA调用else 0,则执行if p_tran_call为0,然后开始tran和回滚。
当然我就是这么做的。
创建过程spB(p_tran_control位)
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调用spA,但如果从spB调用spC,则从保存事务的spA调用spC,则spC将提交事务。即使当自动提交设置为off时;
https://stackoverflow.com/questions/50469734
复制相似问题