如果在同时执行多个插入查询时发生任何错误,如何回滚表

时间:2014-02-09 06:13:59

标签: c# asp.net sql-server

我想在3个不同的表中执行3个插入查询。 但这些所有3个查询都依赖于彼此的手段 当第一个查询成功执行然后应该有 执行第二个查询,然后成功执行第二个查询 应该有第三个查询执行。

如果出现任何服务器错误或任何其他类型错误 执行第二个查询然后它必须删除所有记录 第一次查询插入的数据库。

如果在执行第三次查询时发生错误(成功执行后) 第1和第2个查询)然后必须从数据库中删除所有记录 由第一和第二查询插入。

我可以通过在Catch Block中执行删除查询来实现此目的。这是好主意吗? 或者请给我一个建议,我怎么能实现这个,因为我在工作 现场项目,所以我不能冒任何风险。请尽快回复我。

2 个答案:

答案 0 :(得分:4)

为您做的交易。 看看这个例子:

    SqlConnection myConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Northwind;uid=sa;pwd=sa;");
  myConnection.Open();

  // Start a local transaction
  SqlTransaction myTrans = myConnection.BeginTransaction();

  SqlCommand myCommand = new SqlCommand();
  myCommand.Connection = myConnection;
  myCommand.Transaction = myTrans;
  try
  {
    myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')";
    myCommand.ExecuteNonQuery();
    myCommand.CommandText = "delete * from Region where RegionID=101";

    // Attempt to commit the transaction. 
    myCommand.ExecuteNonQuery();
    myTrans.Commit();
    Response.Write("Both records are written to database.");
  }
  catch (Exception ep)
  {
    // Attempt to roll back the transaction. 
    myTrans.Rollback();
    Response.Write(ep.ToString());
    Response.Write("Neither record was written to database.");
  }
  finally
  {
    myConnection.Close();
  }

答案 1 :(得分:2)

基本上,您希望使用“全有或全无”原则执行这些插入操作:如果所有插入操作都成功执行,则更改应永久(commit - ref)并且如果有错误然后应取消所有更改(rollback - ref)。这意味着您必须使用transactions。更多,我将使用带有try ... catch块(ref)的存储过程来执行此任务:

CREATE PROCEDURE dbo.InsertDataInto3Tables
(
    @T1_Param1 INT, -- or another data type
    @T1_Param2 VARCHAR(50), -- use the proper max. length 
    ...
    @T2_Param1 INT, 
    ...
    @T3_Param1 INT
)
AS
BEGIN

BEGIN TRANSACTION;

BEGIN TRY
    -- First insert
    INSERT INTO dbo.Table1 (Col1, Col2, ...)
    VALUES (@T1_Param1, @T1_Param2, ...);

    -- Second insert
    INSERT INTO dbo.Table2 (Col1, ...)
    VALUES (@T2_Param1, ...);

    -- Third insert
    INSERT INTO dbo.Table3 (Col1, ...)
    VALUES (@T3_Param1, ...);

    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;

    SELECT 
        ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH;
END;

注意#1:如果对于某些表,您必须INSERT两行或更多行,您可以使用table valued parametersref; SQL2008 +)或XML参数(ref

注意#2:在客户端 - 应用程序级别管理事务将增加网络I / O开销。