为原子“获取或创建”场景选择哪个事务隔离级别

时间:2013-11-20 13:47:28

标签: entity-framework transactions entity-framework-6 isolation-level transaction-isolation

哪个事务IsolationLevel最好保证只创建一个Datarow。 假设使用SQL Server 2012和EntityFramework 6。

    using(var db = new XyzContext())
    {
        using(var dbContextTransaction = db.Database.BeginTransaction(???))
        {
            try
            {

                Item obj = db.Item.SingleOrDefault(o => o.Hashcode.Equals(hashCode));

//it is possible that 2 threads are coming through here and both have obj == null

                if(obj == null)
                {
                    obj = db.Item.Add(new Item
                    {
                        Hashcode = hashCode,
                        State = 0,

                    });
                }

                db.SaveChanges();

                dbContextTransaction.Commit();
            }
            catch(Exception)
            {
                dbContextTransaction.Rollback();
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

如果您的方案是更新,则快照是好的(这是ef 6的默认行为)。

但是在你的情况下是插入,那么大多数方法都无法正常工作。

您必须确保您的锁升级级别为表(默认值)。 然后应用 RepeatableRead 事务模式。 它阻止其他线程读取表,直到第一个线程完成。

最好在其中一列上使用唯一约束列而不是此方法。

或者在sql server数据库中创建一个特殊的表,然后在主查询之前将行锁定放在该表的特定记录中。插入,然后做你的工作,你的其他操作没有瓶颈,并且足够快。

祝你好运