2013-07-15 20 views
4

我有一個sql server(server1)和webservice server(server2)。 server2有以下代碼。從客戶端獲得結果請求並更新數據庫。SQL服務器是否自動回滾連接丟失的變化?

try 
     { 
      AppLogger.DebugFormat("Entered into save result - [{0}]", result.ID); 
      int retry = 0; 
      while (++retry <= 5) 
      { 
       try 
       { 
        using (var oConnection = new SqlConnection("Connection string")) 
        { 
         oConnection.Open(); 
         AppLogger.Debug("Saving data into db"); 
         oConnection.Execute("storedproc1", new 
         { 
          param1 = Convert.ToInt32(result.value1), 
          param2 = Convert.ToInt32(result.value2), 
          param3 = result.value3=="Success", 
          param4 = result.vaue4 
         }, commandType: CommandType.StoredProcedure); 
         AppLogger.DebugFormat("Save done with [{0}] try", retry); 
         break; 
        } 
       } 
       catch (SqlException sx) 
       { 
        if (retry == 5) 
        { 
         AppLogger.Debug("sql exception occured"); 
         throw; 
        } 
        else 
        { 
         AppLogger.ErrorFormat("Exception occurred [{0}] time(s), going to retry again after a minute", sx, retry); 
         System.Threading.Thread.Sleep(1000 * 60); 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      AppLogger.Error("Unable to save result", ex); 
      throw; 
     } 

webservice服務器(Server2)發生,以面對藍屏錯誤並死亡。我們重新啓動它,並從應用程序中找到下面的日誌信息。

10:32:41.046 Entered into save result - 100023 
10:32:41.062 Saving data into db 
10:32:41.062 Save done with 0 try 

10:32:45.233 Entered into save result - 100024 
10:32:41.248 Saving data into db 
10:32:41.248 Save done with 0 try 

但是sql server(server1)沒有這個更新。

下面是我的存儲過程

Alter Procedure storedproc1 
@Param1 int, 
@Param2 int, 
@Param4 varchar(2000), 
@Param3 bit 
AS 
SET NOCOUNT ON 

BEGIN 
    Declare @param5 varchar(30) 
    select @param5=col1 from table1 where [email protected] and [email protected] 
    UPDATE table1 set [email protected], [email protected] where [email protected] and [email protected] 

    IF not exists (select 1 from table1 where col1 = @param5 and col5 is null and col4 is null) 
    BEGIN 
     UPDATE table2 set col2='statuschange' 
     where col1 in (select distinct col6 from table1 where [email protected]) 
    END 
END 

能有人指出我爲什麼應用程序服務器保存說做和SQL Server沒有更新?

是否sql服務器回滾連接丟失的變化?

順便說一下,我使用小巧玲瓏與我的數據庫交談。 Log4net通用日誌記錄。

感謝您的時間, 也先

回答

2

在一般情況下,如果當時的連接丟失事務是開放的,該交易將回完全搖。另一方面,如果一個事務被提交,那麼即使服務器在提交後發生崩潰,它的更改也會存活。

您的代碼未顯示任何事務處理。如果SQL代碼在沒有顯式事務的情況下執行,則每個語句在自己的自動事務中運行。因此,每個完成的陳述將被保留。

您看到的行爲指向正在使用的事務並未正確清理。這與事務池一起可能會導致意外的行爲。

跟蹤此操作的一種方法是在using(var oConnection)塊的開頭執行SELECT @@TRANCOUNT;。如果這種情況再次高於預期,則說明您有問題。它需要始終爲0,或者如果將dapper設置爲在事務內部執行代碼,則它總是需要始終爲1。任何大於「默認值」的值都指向事務泄漏。

+0

謝謝@Sebastian Meine,這不是一個常見的情況。它在過去六個月裏發生過一次。 Transcount是0,我想這並不意味着當這個問題發生時它是0。你的解釋讓我看到了這個數據庫處理的其他過程和查詢。一些存儲過程確實使用此表的交易。這些存儲過程同時也可以100%執行。我正在清理交易混亂。因爲我無法重現這個問題。我想清理將在未來有所幫助。謝謝。 – Esen

+0

刪除交易時要小心。爲什麼代碼被封裝在一個事務中可能有一個很好的理由。 (想想將錢從一個賬戶轉移到另一個賬戶的典型例子。)但是,您可能想要統一如何處理它們。您要麼在程序內部進行事務管理,要麼在應用程序層中執行事務管理,或者在應用程序層中執行非事務管理,而在過程中則不執行。並且 - 回顧你最初的問題 - 確保它們總是關閉(提交或回滾),無論它們如何被打開並且獨立於潛在的錯誤情況。 –