【问题标题】:Why the transaction insert 2 values when fails the first one?为什么交易在第一个失败时插入 2 个值?
【发布时间】:2019-05-25 18:16:48
【问题描述】:

我有这张桌子:

TableAB
{
    IDTableA;
    IDTableB;
}

我在表格中有一行,(1,2)。现在我想插入一些其他值,并且我想在事务中进行。我用这个:

begin
insert into TableAB (IDTAbleA, IDTAbleB) VALUES(1,2);
insert into TableAB (IDTAbleA, IDTAbleB) VALUES(1,3);
insert into TableAB (IDTAbleA, IDTAbleB) VALUES(1,3);
commit

第一次插入时出现完整性错误,但第二次和第三次插入时,会将值插入表中。

我如何使用事务并且第一个失败,为什么它会插入另外两行?我想在事务中,如果某些事情失败了,一切都会中止。那么在这种情况下,使用事务和不使用事务有什么区别呢?

谢谢。

【问题讨论】:

  • “我认为在事务内部,如果某些事情失败了,一切都会中止。” -- 对某些(大多数?)DBMS 来说是正确的。对于 SQL Server,您可能需要更改设置,请参阅stackoverflow.com/questions/1749719/…

标签: sql-server tsql transactions


【解决方案1】:

我认为您应该将内容包装在 TRY...CATCH 中。

BEGIN TRY

    BEGIN TRANSACTION InsertValues;
    INSERT INTO TableAB (IDTAbleA, IDTAbleB) VALUES(1,2);
    INSERT INTO TableAB (IDTAbleA, IDTAbleB) VALUES(1,3);
    INSERT INTO TableAB (IDTAbleA, IDTAbleB) VALUES(1,3);
    COMMIT InsertValues;

END TRY
BEGIN CATCH

    ROLLBACK InsertValues;
    THROW;

END CATCH

【讨论】:

    【解决方案2】:

    您需要使用TRYCATCH,并且在CATCH 中您必须使用ROLLBACK 就像已经提到的事务。另一种方法是SET XACT_ABORT ON,如下所示。

    SET XACT_ABORT ON 
    
    BEGIN TRAN
    insert into TableAB (IDTAbleA, IDTAbleB) VALUES(1,2);
    insert into TableAB (IDTAbleA, IDTAbleB) VALUES(1,3);
    insert into TableAB (IDTAbleA, IDTAbleB) VALUES(1,3);
    COMMIT TRAN
    

    【讨论】:

      【解决方案3】:

      试试这个:

      SET XACT_ABORT ON
      BEGIN TRANSACTION;
      
      BEGIN TRY
      
          INSERT INTO TableAB(IDTAbleA,IDTAbleB)VALUES(1, 2);
          INSERT INTO TableAB(IDTAbleA,IDTAbleB)VALUES(1, 3);
          INSERT INTO TableAB(IDTAbleA,IDTAbleB)VALUES(1, 3);
      
          COMMIT TRANSACTION;
      END TRY
      BEGIN CATCH
      
          IF @@TRANCOUNT > 0
          BEGIN
      
              IF (XACT_STATE()) = -1
              BEGIN
                  ROLLBACK TRANSACTION;
                  THROW;
              END
              ELSE IF (XACT_STATE()) = 1
              BEGIN
                  COMMIT TRANSACTION;
              END;
      
          END;
      
      END CATCH;
      

      阅读更多:

      XACT_ABORThttps://docs.microsoft.com/en-us/sql/t-sql/statements/set-xact-abort-transact-sql?view=sql-server-2017

      XACT_STATE()https://docs.microsoft.com/en-us/sql/t-sql/functions/xact-state-transact-sql?view=sql-server-2017

      @@TRANCOUNThttps://docs.microsoft.com/en-us/sql/t-sql/functions/trancount-transact-sql?view=sql-server-2017

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-16
        • 2021-08-03
        • 1970-01-01
        • 2020-01-31
        • 2014-05-15
        • 2018-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多