如何控制并发来更新3个数据库表

本文关键字:更新 3个 数据库 并发 何控制 控制 | 更新日期: 2023-09-27 18:22:45

当我点击表单上的保存按钮时

它调用3种方法:

save_Purchase();
save_dtPurcaseProduct();
save_dtPurchaseProductExp();

这3种方法将更改保存到3个数据库表

因此,场景是要么所有3个表都应该更新,要么没有一个表得到更新。

我使用C#和Microsoft sql server作为数据库

如何控制并发来更新3个数据库表

如果不想重写函数,可以使用TransactionScope:

using (TransactionScope scope = new TransactionScope())
{
    try
    {
        save_Purchase();
        save_dtPurcaseProduct();
        save_dtPurchaseProductExp();
        scope.Complete(); //All goes well, then commit your transaction
    }
    catch(Exception ex)
    {
         //Do not call complete, on exit of transactionscope, transaction will rollback
    }
}

而不是向数据库发送3个调用。您应该编写一个存储过程来为您执行所有3个函数。您应该在那里申请交易。如何在存储过程中实现事务。

如果您想保留这3个方法,那么您也可以在代码级别应用事务。

      SqlConnection conn = new SqlConnection("Your Connection string");
      conn.Open()
      using (SqlTransaction tran = conn.BeginTransaction()) {
      try {
      // your code
      tran.Commit();
      }  catch {
       tran.Rollback();
       throw;
      }
      }

所有更新语句都必须在transaction内。更多

如果使用的是Stored procedure,请使用以下方法编写存储过程。即所有三个CCD_ 3语句CCD_。这样,如果一切都更新了,你就可以提交它,否则它将被回滚

CREATE/ALTER PROCEDURE Proc_Name
AS
BEGIN TRY
   BEGIN TRAN
-- Your Update Statements
     COMMIT TRAN
END TRY
BEGIN CATCH
    ROLLBACK TRAN
END CATCH

如果您使用的是SQL查询和ADO

使用以下方法

private static void Update() 
   {
      SqlConnection db = new SqlConnection("strConectionString");
      SqlTransaction transaction;
      db.Open();
      transaction = db.BeginTransaction();
      try 
      {
         new SqlCommand("update quey1", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("update quey2", db, transaction)
            .ExecuteNonQuery();
         new SqlCommand("update quey3", db, transaction)
            .ExecuteNonQuery();
         transaction.Commit();
      } 
      catch (SqlException sqlError) 
      {
         // always log or rethrow exceptions!
         transaction.Rollback();
         db.Close();
         //
         throw;
      }
      db.Close();
   }

[已编辑]当你遇到故障时,你应该总是记录(如果你能处理的话)或重新抛出它;关键的诊断信息将被"捕获"块所吞噬。

在这种情况下,我建议重新向外抛出——因为最外层的系统或应用程序线程应该处理异常,并在此时记录它。如果发生异常,则更新明显失败&业务逻辑不应该继续。