2013-02-19 79 views
6

當我將數據保存在數據庫中時,我使用了TransactionScope並將IsolationLevel設置爲Serializable。完成交易後更改TransactionScope IsolationLevel

TransactionOptions options = new TransactionOptions 
     { 
      IsolationLevel=IsolationLevel.Serializable 
     }; 


using (var transaction = new TransactionScope(TransactionScopeOption.Required,options)) 
{ 
    transation.Complete(); 
} 

現在執行結束後,我想更改TransactionScopeIsolationLevel。

編輯

我的理解是這樣的,如果IsolationLevel將設置爲序列,然後完成交易後,連接對象被關閉並返回到連接池,當其他一些請求到達它取從連接對象該池因此受到之前IsolationLevel的影響。所以我想在每次事務之後將隔離級別更改爲默認級別。

回答

5

您是對的:在將連接返回到池時,隔離級別未被重置。這是可怕的行爲,但我們都堅持了下來......

有兩種策略:

  1. 返回之前復位的隔離級別:這是你的方法。
  2. 始終使用與顯式事務(或TransactionScope)的連接,以確保隔離級別。

我建議你做後者。

如果您堅持要做(1),只需在關閉TransactionScope後更改隔離級別,但必須對連接對象執行此操作。例如:

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    using (var transaction = new TransactionScope(TransactionScopeOption.Required,options)) 
    { 
     connection.Open(); //open inside of scope so that the conn enlists itself 
     transation.Complete(); 
    } 
    //conn is still open but without transaction 
    conn.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL XXX"); //pseudo-code 
} //return to pool 

這是否適合您?

+0

感謝您的迴應,我準備接受其他更好的選擇,但是根據您建議以明確的交易打開所有連接,您是否認爲這會在系統中帶來很多開銷。我有一個巨大的應用程序數百個端點,但只有幾個場景,我使用TransactionScope。你對這樣的事情有什麼建議? – MegaMind 2013-02-19 12:59:43

+0

無論如何,所有語句都使用隱式事務,因此事務開銷幾乎不變。如果你無法遷移一切,你的方法實際上可能是一個好主意。黑客,但一個實用的解決方案。我看不出任何重大問題。 – usr 2013-02-19 13:47:39

+0

does conn.ExecuteCommand(「SET TRANSACTION ISOLATION LEVEL XXX」);工作?有人試過嗎? – hazimdikenli 2015-06-26 11:02:57

2

我一直在這一點。幸運的是連接字符串邏輯是集中的。我所做的是更改連接字符串的應用程序設置,如果Transaction.Current不爲空(這意味着我們在一個TransactionScope中)。

通過這種方式,TransactionScope連接不會與其他人共享。