如何在SQL Server上找到当前数据库的事务级别?
sql sql-server sql-server-2005 isolation-level sql-server-2008
正如先前的Stack Overflow问题(TransactionScope和连接池以及SqlConnection如何管理IsolationLevel?)所证明的那样,事务隔离级别在SQL Server和ADO.NET(也是System.Transactions和EF)的池化连接中泄漏,因为它们建立在ADO.NET).
这意味着,在任何应用程序中都可能发生以下危险事件序列:
问题:防止这种情况的最佳方法是什么?现在到处都需要使用显式交易吗?
这是一个独立的复制品.您将看到第三个查询将继承第二个查询中的Serializable级别.
class Program
{
static void Main(string[] args)
{
RunTest(null);
RunTest(IsolationLevel.Serializable);
RunTest(null);
Console.ReadKey();
}
static void RunTest(IsolationLevel? isolationLevel)
{
using (var tran = isolationLevel == null ? null : new TransactionScope(0, new TransactionOptions() { IsolationLevel = isolationLevel.Value }))
using (var conn = new SqlConnection("Data Source=(local); Integrated Security=true; Initial Catalog=master;"))
{
conn.Open();
var cmd = new SqlCommand(@"
select
case transaction_isolation_level
WHEN 0 THEN 'Unspecified'
WHEN 1 THEN …Run Code Online (Sandbox Code Playgroud) 我对事务范围和实体框架有点兴奋.
最初,我们希望应用程序中的所有连接在读取数据时使用快照隔离级别,但在某些情况下,我们希望使用read committed或read uncommitted隔离级别读取数据,为此我们将使用事务范围来临时更改隔离级别查询(如此处和不同博客中的几篇帖子所述).
但问题是,当处理事务范围时,隔离仍然保留在连接上,这会引起相当多的问题.
我尝试了所有类型的变化,但结果相同; 隔离级别保留在事务范围之外.
是否有人可以为我解释这种行为或者可以解释我做错了什么?
我已经通过将事务范围封装在一个为我恢复隔离级别的一次性类中找到了解决问题的方法,但是我希望对这种行为有一个很好的解释,我认为这种行为不仅影响我的代码,而且其他人也是.
这是一个说明问题的示例代码:
using (var context = new MyContext())
{
context.Database.Connection.Open();
//Sets the connection to default read snapshot
using (var command = context.Database.Connection.CreateCommand())
{
command.CommandText = "SET TRANSACTION ISOLATION LEVEL SNAPSHOT";
command.ExecuteNonQuery();
}
//Executes a DBCC USEROPTIONS to print the current connection information and this shows snapshot
PrintDBCCoptions(context.Database.Connection);
//Executes a query
var result = context.MatchTypes.ToArray();
//Executes a DBCC USEROPTIONS to print the current connection information and this still shows snapshot
PrintDBCCoptions(context.Database.Connection);
using (var …Run Code Online (Sandbox Code Playgroud)