相关疑难解决方法(0)

147
推荐指数
5
解决办法
11万
查看次数

SQL Server:池化连接中的隔离级别泄漏

正如先前的Stack Overflow问题(TransactionScope和连接池以及SqlConnection如何管理IsolationLevel?)所证明的那样,事务隔离级别在SQL Server和ADO.NET(也是System.Transactions和EF)的池化连接中泄漏,因为它们建立在ADO.NET).

这意味着,在任何应用程序中都可能发生以下危险事件序列:

  1. 发生请求,需要显式事务以确保数据一致性
  2. 任何其他请求都不会使用显式事务,因为它只进行非关键的读取.此请求现在将作为可序列化执行,可能导致危险的阻塞和死锁

问题:防止这种情况的最佳方法是什么?现在到处都需要使用显式交易吗?

这是一个独立的复制品.您将看到第三个查询将继承第二个查询中的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)

t-sql sql-server ado.net transactions transactionscope

53
推荐指数
3
解决办法
9465
查看次数

处理Transactionscope后,Entity Framework和Transactionscope不会还原隔离级别

我对事务范围和实体框架有点兴奋.

最初,我们希望应用程序中的所有连接在读取数据时使用快照隔离级别,但在某些情况下,我们希望使用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)

.net ado.net entity-framework transactions transactionscope

12
推荐指数
1
解决办法
4635
查看次数