如何在全球所有实体框架的交易变化的IsolationLevel [英] How to globally change IsolationLevel of all Entity Framework transactions

查看:152
本文介绍了如何在全球所有实体框架的交易变化的IsolationLevel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我评估EF为我的下一个新的应用程序。

I am evaluating EF for my next new apps.

我怎样才能改变在全球所有EF交易的IsolationLevel在应用程序? 例:假设我想用读提交快照

How can I globally change the IsolationLevel of all EF transactions in an application? Ex: Suppose I want to use "Read Committed Snapshot".

虽然它是确定指定的IsolationLevel时,我明确地反正需要一个TransactionScope(见下文code),这将是丑陋的具有封装每个EF保存操作在一个TransactionScope。

While it is OK to specify the IsolationLevel when I explicitely need a TransactionScope anyway (see code below) it would be ugly having to encapsulate every EF save operation in a TransactionScope.

 'OK
    Using tsc As New TransactionScope(TransactionScopeOption.RequiresNew, TransactionOption.ReadCommitted)
        UpdateShoppingCart
        EnqueueNewOrder
        SendConfirmationEmail
        tsc.Complete
    End Using

    'Is this really the only way to avoid Serializable?
    Using tsc As New TransactionScope(TransactionScopeOption.RequiresNew, TransactionOption.ReadCommitted)
      _ctx.SaveChanges()
      tsc.Complete
    End Using

    Class TransactionOption
        Public Shared ReadOnly ReadCommitted As New TransactionOptions() With {
            .IsolationLevel = IsolationLevel.ReadCommitted,
            .Timeout = TransactionManager.DefaultTimeout
            }
    End Class

我认为混合IsolationLevles是不是一个好主意。难道我错了吗?

I assume mixing IsolationLevles is not a good idea. Am I wrong with that?

通过序列化和SQL Server(相对于甲骨文)将一个简单的无辜样子读取可能导致转换锁死锁。

With Serializable and SQL Server (in contrast to Oracle) inserting a simple innocent looking read may cause a conversion lock deadlock.

从EF常见问题解答: 我们建议您使用读提交的事务,并使用READ COMMITTED快照隔离,如果你需要有读者不会阻止作家和作家不会阻止读者。

From the EF FAQ: "It is recommended that you use READ COMMITTED transactions, and use READ COMMITTED SNAPSHOT ISOLATION if you need to have readers not block writers and writers not block readers."

我不明白为什么EF默认为可序列化,并使得它如此难以改变默认的隔离级别 - 与SQL Server(相对于Oracle的多版本),默认为悲观并发模型。配置选项应该是很容易实现 - ?还是我失去了一些东西在这里

I do not understand why EF defaults to Serializable and makes it so difficult to change the default isolation level - with SQL Server (in contrast to Oracle's multi-versioning) defaulting to a pessimistic concurrency model. A configuration option should be very easy to implement - or am I missing something here?

推荐答案

我几乎可以肯定,默认EF事务隔离级别是根据使用的数据库供应商。 的SaveChanges 执行此code:

I'm almost sure that default EF transaction isolation level is based on used database provider. SaveChanges executes this code:

    ... 
    try
    {
        this.EnsureConnection();
        flag = true;
        Transaction current = Transaction.Current;
        bool flag2 = false;
        if (connection.CurrentTransaction == null)
        {
            flag2 = null == this._lastTransaction;
        }
        using (DbTransaction transaction = null)
        {
            if (flag2)
            {
                transaction = connection.BeginTransaction();
            }
            objectStateEntriesCount = this._adapter.Update(this.ObjectStateManager);
            if (transaction != null)
            {
                transaction.Commit();
            }
        }
    }
    ...

正如你可以看到的BeginTransaction 被称为无的IsolationLevel 指定。引擎盖下用 IsolationLevel.Unspecified 创建提供商特定的事务。未指定的隔离级别应导致缺省隔离级别的数据库服务器/驱动器。在SQL Server的默认隔离级别为 READ COMMITED 所以我希望它应该使用它,但我还没有测试它。

As you can see BeginTransaction is called without IsolationLevel specified. Under the hood it creates provider specific transaction with IsolationLevel.Unspecified. Unspecified isolation level should result in default isolation level for database server / driver. In SQL Server default isolation level is READ COMMITED so I expect it should use it but I haven't tested it yet.

如果你想在全球范围内改变隔离级别,你可以覆盖的SaveChanges 在你的类从的ObjectContext 导出并包裹 base.SaveChanges()在自定义的的TransactionScope

If you want to globally change isolation level you can override SaveChanges in your class derived from ObjectContext and wrap base.SaveChanges() in custom TransactionScope.

这篇关于如何在全球所有实体框架的交易变化的IsolationLevel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆