簡體   English   中英

提交/回滾后,SQL Server 2008 R2中快照隔離級別中來自ADO.Net的事務未更改為默認隔離級別

[英]Transaction from ADO.Net in Snapshot Isolation Level in SQL Server 2008 R2 not changing to default isolation level after commit/rollback

我在C#中使用ADO.NET編寫以下代碼,以使用SNAPSHOT隔離級別更新SQL Server 2008 R2數據庫中的數據。 該代碼運行良好。 但是,如果此后我轉到ASP.Net應用程序中的另一個頁面,在此數據庫表與同一服務器上的另一個數據庫表連接的查詢之間運行查詢,則會收到一條錯誤消息:

System.Data.SqlClient.SqlException:快照隔離事務無法訪問數據庫'Member_Security',因為此數據庫中不允許快照隔離。 使用ALTER DATABASE允許快照隔離。

如果查詢在SNAPSHOT事務代碼之后運行,則會引發如上所述的錯誤:

select 
   e.EmpId, e.EmpHours, m.SecurityLevel, m.IsPriveleged 
from 
   Emp e 
inner join 
   Member_Security.dbo.Members m

如果我未在SNAPSHOT級別的以下代碼中運行事務,則沒有問題。

為什么會發生這種情況,我該如何糾正?

我認為在這種情況下,SNAPSHOT隔離級別沒有重置為運行此代碼之前的水平。

完美運行的代碼:

con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["EMP"].ConnectionString;
con.Open();
tran = con.BeginTransaction(IsolationLevel.Snapshot);  
cmd = new SqlCommand();
cmd.CommandTimeout = 0; 
cmd.Connection = con;
cmd.Text = "Update emp set empcomm = 200 where empage > 40;"
cmd.Transaction = tran;

try {
    cmd.ExecuteNonQuery();
    tran.Commit();
}
catch(Exception ex)
{
    try 
    { 
        if(tran != null) 
           tran.rollback();
    } 
    catch{}
}
finally 
{ 
     DAL.ResetTransactionIsolationLevel(); 
} //NEED THIS TO SOLVE THIS PROBLEM

更新1:

似乎使用隔離級別而不是根據來自以下URL的本段規定的ADO.Net代碼中的默認隔離級別時存在問題:在ADO.Net代碼中使用非默認隔離級別時,需要顯式設置隔離級別

提交或回滾事務后,該事務的隔離級別對於處於自動提交模式(SQL Server默認設置)的所有后續命令保持不變。 這可能會產生意外的結果,例如REPEATABLE READ的隔離級別持續存在,並將其他用戶鎖定在一行之外。 要將隔離級別重置為默認值(READ COMMITTED),請執行Transact-SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED語句,或調用SqlConnection.BeginTransaction,然后立即調用SqlTransaction.Commit。 有關SQL Server隔離級別的更多信息,請參見SQL Server聯機叢書中的“數據庫引擎中的隔離級別”。

更新2:

我避免這種情況的唯一方法是在完成上述事務后將隔離級別設置為Read Committed,即在上述事務的finally塊中調用方法'ResetTransactionIsolationLevel'。 如果這樣做,那么在SNAPSHOT隔離級別之后執行跨數據庫查詢時,我看不到任何問題。 我添加了finally塊以在上面的代碼片段中顯示此解決方案。

 public static void ResetTransactionIsolationLevel()
    {
        SqlCommand cmd = new SqlCommand();
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["EMP"].ConnectionString);


        try
        {
            cmd.CommandText = "set transaction isolation level read committed";
            cmd.CommandType = CommandType.Text;
            cmd.Connection = conn;
            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();
        }
        finally
        {
            cmd.Dispose();
            conn.Close();
            conn.Dispose();
        }
    }

從此處: http : //msdn.microsoft.com/zh-cn/library/tcbchxcb( v=vs.110) .aspx在事務中使用快照隔離之前,必須通過在數據庫上設置ALLOW_SNAPSHOT_ISOLATION ON來啟用快照隔離。

在您的數據庫上運行此命令:

ALTER DATABASE MyDatabase
SET ALLOW_SNAPSHOT_ISOLATION ON

UPDATE如果您想在后續事務中讀取Committed SNAPSHOT而不隱式指定,請運行:

ALTER DATABASE MyDatabase
SET READ_COMMITTED_SNAPSHOT ON

請注意,這不是讀提交的,並且所有數據仍在通過tempdb,因此您確實需要考慮數據庫和應用程序的容量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM