简体   繁体   English

存储过程中的事务不会回滚

[英]Transaction in stored procedure not rolling back

I have stored procedure sp_Insert with 2 options eg. 我已经存储了带有2个选项的sp_Insert过程。 INSERT INTO Table1 and INSERT INTO Table2 . INSERT INTO Table1INSERT INTO Table1 INSERT INTO Table2

I have declared 3 variables @choice (which can be 1 , 2 or 3 ), @insertDataToTable1 and @insertDataToTable2 as inputs. 我已经声明3个变量@choice (其可以是123 ), @insertDataToTable1@insertDataToTable2作为输入。

So code structure looks like: 因此,代码结构如下所示:

CREATE PROC sp_MyProc
@choice... 
@insertDataToTable1...
@insertDataToTable2...
AS
BEGIN TRAN
IF(@choice = 1 OR @choice = 3) 
BEGIN
   BEGIN TRY
      //my query to insert to Table 1
   END TRY
   BEGIN CATCH
      // print error
      ROLLBACK //should rollback transaction
      RETURN
   END CATCH
END
ELSE IF (@choice = 2 OR @choice = 3)
BEGIN
   BEGIN TRY
      //my query to insert to Table 1
   END TRY
   BEGIN CATCH
      // print error
      ROLLBACK //should rollback transaction
      RETURN
   END CATCH
END
COMMIT

So If @choice = 1 than run only first query (instert to table1), if @choice = 2 run only 2nd query (inster to 2nd table), if @choice = 3 run both 1st and 2nd queries to insert databa to 1st and 2nd table. 因此,如果@choice = 1不是仅运行第一个查询(插入到table1),如果@choice = 2只能运行第二查询(插入到第二个表),如果@choice = 3运行第一和第二查询,则将@choice = 3插入到第一和第二查询。第二张桌子。

PROBLEM: 问题:

Everything would be fine, except problem with transaction. 一切都很好,除了交易问题。 Transaction not rolling back if one of blocks fails. 如果其中一个块失败,则事务不会回滚 I mean If 1st query is succssful (inserted data to table1) and second query fails (for example problems with primary key) It not rolling back, value stay inserted to table1. 我的意思是,如果第一个查询成功(将数据插入到table1中),而第二个查询失败(例如主键问题),它不会回滚,则将值保留插入到table1中。 Where is the problem? 问题出在哪儿?

You will never meet both conditions even if you would do @choice = 3 as you have ELSE IF in the second condition. 即使您执行@choice = 3,也不会满足这两个条件,因为您在第二个条件中具有ELSE IF。 When you make @choice = 3 then the first IF would be true and it will not go to the ELSE. 当您使@choice = 3时,第一个IF将为true,并且不会进入ELSE。 If you want to go to the second part change ELSE IF to just IF. 如果要转到第二部分,请将ELSE IF更改为IF。

CREATE TABLE a (a int)
GO

CREATE PROC sp_MyProc
@choice int
AS
BEGIN TRAN
IF(@choice = 1 OR @choice = 3) 
BEGIN
   BEGIN TRY
      INSERT INTO a VALUES (1);
   END TRY
   BEGIN CATCH
      PRINT 'WAS HERE'
      ROLLBACK 
      RETURN
   END CATCH
END
IF (@choice = 2 OR @choice = 3)
BEGIN
   BEGIN TRY
      INSERT INTO a VALUES ('a');
   END TRY
   BEGIN CATCH
      PRINT 'WAS HERE 2'
      ROLLBACK 
      RETURN
   END CATCH
END
COMMIT
GO
EXEC sp_MyProc 3
GO
SELECT * FROM a
GO
DROP TABLE a;
GO
DROP PROC sp_MyProc
GO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM