2017-08-01 21 views
0
public static void SetStatus(Status statusObject,int retryCount) 
{ 
    if (statusObject != null) 
    { 
     using (SqliteConnection dbConn = new SqliteConnection(dbURL)) 
     { 
      IDbTransaction dbTransaction = null; 
      try 
      { 
       dbConn.Open(); 
       dbTransaction = dbConn.BeginTransaction(); 
       new SqliteCommand(some_query, dbConn).ExecuteNonQuery(); 
      } 
      catch (Exception e) 
      { 
       dbTransaction.Rollback(); 
       dbConn.Close(); 
       if (retryCount > 0) 
       { 
        SetStatus(statusObject, --retryCount); 
        return; 
       } 
       else 
        throw e; 
      } 
      finally 
      { 
       try { dbTransaction.Commit(); } 
       catch (Exception e) 
       { 

       } 
      } 
     } 
    } 
} 

當的ExecuteNonQuery由於一些例外,我都將在運行again.In這種情況下,相同的查詢重試機制失敗,因爲第二次(而重試)以下異常comes-連接必須是有效和開放爲sqllite數據庫提交事務的同時重新嘗試執行失敗的查詢

「連接必須是有效的,開放的,以提交事務」

+0

提交後,最後關閉你的數據庫連接。 –

回答

0

問題基本上是,您在finally塊中承諾交易 - 即使您已經回滾了交易並關閉了catch塊中的連接,該塊總是按設計運行。

更簡單的方法是在仍然位於try塊中的情況下提交交易,因爲畢竟,如果try中的所有代碼都成功,您只想提交交易。

這就是說,你有一些奇怪的嵌套與tryusing構造那裏。你應該儘量保持像using這樣的簡潔。這樣你就不必自己處理關閉連接。事情是這樣的:

public static void SetStatus(Status statusObject, int retryCount) 
{ 
    if (statusObject == null) 
     return; 

    try 
    { 
     using (var dbConn = new SqliteConnection(dbURL)) 
     { 
      IDbTransaction dbTransaction = null; 
      try 
      { 
       dbConn.Open(); 
       dbTransaction = dbConn.BeginTransaction(); 
       new SqliteCommand(some_query, dbConn).ExecuteNonQuery(); 
       dbTransaction.Commit(); 
      } 
      catch 
      { 
       // transaction might be null if the connection couldn’t be opened 
       dbTransaction?.Rollback(); 
       throw; 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     if (retryCount > 0) 
      SetStatus(statusObject, --retryCount); 
     else 
      throw ex; 
    } 
} 

最後一個音符,人們可能認爲使用一個交易是絕對沒有必要在這裏:你只執行該數據庫連接上單個查詢,因此無論是工作,還是會在失敗這種情況下,無論如何都不會有任何回滾。所以,除非你有多個查詢,否則你不需要一個顯式的事務(但我只是假設你只是簡化了你的例子來顯示一個查詢)。

+0

這正是我所做的。感謝解釋。 – DChamp

0

我不好,搞砸了用「終於」不當myself.So如果查詢失敗在第一嘗試它會去捕獲塊將啓動調用重新運行查詢。第二次查詢執行將是成功並且事務將被提交。然後控制轉到最後的第一個查詢,它將再次嘗試提交已經回滾的事務。所以,它會拋出這個異常。 因此,如果將提交移動到主try塊來解決問題。

相關問題