Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与实体框架的并发性&;SQL(ADO.NET)_C#_Entity Framework_Exception_Concurrency_Optimistic Concurrency - Fatal编程技术网

C# 与实体框架的并发性&;SQL(ADO.NET)

C# 与实体框架的并发性&;SQL(ADO.NET),c#,entity-framework,exception,concurrency,optimistic-concurrency,C#,Entity Framework,Exception,Concurrency,Optimistic Concurrency,我有一个并发问题。我阅读了中的乐观并发处理 我有一段代码可以在我的WCF服务中实际测试这一点: public GameResult PurchaseGameItem(int itemId) { using (var entities = new GameEntities()) { var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault();

我有一个并发问题。我阅读了中的乐观并发处理

我有一段代码可以在我的WCF服务中实际测试这一点:

    public GameResult PurchaseGameItem(int itemId)
    {
        using (var entities = new GameEntities())
        {
            var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault();
            p1.Coins = 1;

            using (var e2 = new GameEntities())
            {
                var p2 = e2.Items.Where(p => p.ID == itemId).FirstOrDefault();
                p2.Coins = 2;
                e2.SaveChanges();
            }

            entities.SaveChanges();
        }

        return GameResult.Success;
    }
此外,我还将模型中的“Coins”并发模式设置为“Fixed”。但是,这会发生,保存在数据库中的值为“1”。我尝试了几组值,所以它不是“偶然正确的”。为什么这里没有提出乐观的例外

[update#1]通过尝试下面的第一个响应并将它们组合在一起,我有时成功地得到了一个DbUpdateConcurrencyException。这仍然不是我所期望的乐观的例外,但它确实是一种东西。基本上我不知道为什么它没有一直发生

            var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault();
            var p3 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault();

            p1.CoinValue = 14;
            p3.CoinValue = 115;

            using (var e2 = new GameEntities())
            {
                var p2 = e2.Items.Where(p => p.ID == itemId).FirstOrDefault();
                p2.CoinValue = 72;
                e2.SaveChanges();
            }

            entities.SaveChanges(); // This throws DbUpdateConcurrencyException, perhaps 50% of the time.
看起来这里有一个并发问题!!:D

[更新#2]好吧,我现在算出了其中的一部分,大部分是愚蠢的用户错误。DbUpdateConcurrencyException只抛出一次,因为第二次之后,第二个子句将把它更新为它已经存在的值,因此该部分是逻辑的。如果从同一个上下文中获取了两个实体,则只需考虑后一个更改,因此在第一个响应建议的“一个数据库连接”情况下,不会引发并发异常。这是合乎逻辑的,因为不通过多个句柄访问对象取决于程序员


但我不明白的是DbUpdateConcurrencyException和OptimisticConcurrencyException之间的区别。我无法提出后者。

我很奇怪你为什么创建了两个到数据库的连接

public GameResult PurchaseGameItem(int itemId)
{
    using (var entities = new GameEntities())
    {
        var p1 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault();
        var p2 = entities.Items.Where(p => p.ID == itemId).FirstOrDefault();

        p1.Coins = 1;
        p2.Coins = 2;

        entities.SaveChanges();
    }

    return GameResult.Success;
}

OptimisticConcurrencyException来自ADO.NET,它是ADO.NET实体框架的基础。DbUpdateConcurrencyException由实体框架生成。如果不通过连接/命令对象直接使用ADO.NET,则在使用实体框架时不应遇到OptimisticConcurrencyException。

我的逻辑只是为了模拟发生并发问题的更现实场景。它不是任何类型的实际的、功能性的代码。也就是说,您的方法会产生相同的结果。没有错误。哦,正如我在更新中提到的,这不会引起任何错误。您只需要在同一个上下文中获得对同一对象的两个引用,这不是问题(除非我误解了整个过程的工作原理)。是的,您需要两个到DBContext的连接,这两个连接在同一时间内更改了记录数据库中的相同内容,而不会获得ConcurrencyException。