存储过程中的事务不回滚
Transaction in stored procedure not rolling back
我存储过程 sp_Insert
有 2 个选项,例如。 INSERT INTO Table1
和 INSERT INTO Table2
。
我已经声明了 3 个变量 @choice
(可以是 1
、2
或 3
)、@insertDataToTable1
和 @insertDataToTable2
作为输入。
所以代码结构如下:
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 运行 only first query (instert to table1), if @choice = 2
运行 only 2nd query (inster to 2nd table), if @choice = 3
运行 第一个和第二个查询将数据库插入到第一个和第二个 table.
问题:
一切都会好起来的,除了交易问题。 如果其中一个区块失败,交易不会回滚。我的意思是如果第一个查询成功(将数据插入 table1)并且第二个查询失败(例如主键问题)它不会回滚,值会保持插入到 table1。问题出在哪里?
即使您在第二个条件中有 ELSE IF 时执行 @choice = 3 ,您也永远不会同时满足这两个条件。当您设置@choice = 3 时,第一个 IF 将为真,它不会进入 ELSE。如果您想转到第二部分,请将 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
我存储过程 sp_Insert
有 2 个选项,例如。 INSERT INTO Table1
和 INSERT INTO Table2
。
我已经声明了 3 个变量 @choice
(可以是 1
、2
或 3
)、@insertDataToTable1
和 @insertDataToTable2
作为输入。
所以代码结构如下:
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 运行 only first query (instert to table1), if @choice = 2
运行 only 2nd query (inster to 2nd table), if @choice = 3
运行 第一个和第二个查询将数据库插入到第一个和第二个 table.
问题:
一切都会好起来的,除了交易问题。 如果其中一个区块失败,交易不会回滚。我的意思是如果第一个查询成功(将数据插入 table1)并且第二个查询失败(例如主键问题)它不会回滚,值会保持插入到 table1。问题出在哪里?
即使您在第二个条件中有 ELSE IF 时执行 @choice = 3 ,您也永远不会同时满足这两个条件。当您设置@choice = 3 时,第一个 IF 将为真,它不会进入 ELSE。如果您想转到第二部分,请将 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