【问题标题】:Nested transaction can't be rolled back嵌套事务无法回滚
【发布时间】:2016-02-09 13:58:40
【问题描述】:

我有 SQL Server 2008 并且想做这样的事务:

begin transaction oo;

......

begin try        
    save transaction xx;
    alter table ....; -- this will fail
    alter table ....;
    alter table ....;
end try
begin catch  
    rollback transaction xx; -- error here
end catch;

......

commit transaction oo;

rollback transaction xx;,我收到消息

3931 当前事务无法提交,也无法回滚到保存点。回滚整个事务。

我在这里做错了什么?

更新解释场景:

  • 有一个大事务“oo”,它将数据库的表结构从产品版本X更改为产品版本Y。

  • 在嵌套事务中,应尝试更改用户特定表(= 内部事务)。

  • 如果用户特定表因某种原因损坏,则不应回滚整个产品升级过程。

  • 另一方面,如果在主产品表升级(外部事务)期间出现其他故障,则不应升级用户特定表。

【问题讨论】:

  • 你从哪里开始交易 xx?
  • 嵌套事务是一个神话。您可以做一些可以模仿嵌套事务的事情,但最好接受它们不存在并重新考虑您的流程。有数百页解释了嵌套事务的神话。这是其中的几个。 sqlskills.com/blogs/paul/…sqlwithmanoj.com/2015/05/26/…

标签: sql sql-server transactions


【解决方案1】:

Reference

您必须在 CATCH 块内使用此行

ROLLBACK TRANSACTION; 

这将回滚所有事务, 当您在上述声明中使用这个(发布在 Q 中)时,它将 给我们错误

COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION。

为此,您必须将此行放在TRY 块中

COMMIT TRANSACTION oo;

最后你的陈述是这样的

BEGIN TRANSACTION oo;

BEGIN TRY        
    SAVE TRANSACTION xx;
    CREATE TABLE test (ID INT); -- this will fail from second time
    SELECT 3;

    COMMIT TRANSACTION oo;
END TRY

BEGIN catch  

    ROLLBACK TRANSACTION; 
END CATCH;

更新评论后

BEGIN TRY        
    BEGIN TRANSACTION xx1;
    select 1; -- this will always success
    COMMIT TRANSACTION xx1;

    BEGIN TRANSACTION xx2;
    CREATE TABLE test (id int); -- this will fail from second time
    COMMIT TRANSACTION xx2;

    BEGIN TRANSACTION xx3;
    select 3; -- this will fail from second time
    COMMIT TRANSACTION xx3;


END TRY

BEGIN catch  

    ROLLBACK TRANSACTION 
END CATCH;

【讨论】:

  • 感谢您的回答。唉,这不是我要找的。我有以下场景:有一个大事务“oo”,它将数据库的表结构从产品版本 X 更改为产品版本 Y。在嵌套事务中,应尝试更改用户特定表。如果用户特定的表以某种方式损坏,则不应破坏整个产品升级过程。另一方面,如果在主要产品表(外部事务)期间出现其他故障,则不应升级用户特定表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
相关资源
最近更新 更多