2

I have an issue with some concurrency. I read into the Optimistic Concurrency Handling in http://blogs.msdn.com/b/alexj/archive/2009/05/20/tip-19-how-to-use-optimistic-concurrency-in-the-entity-framework.aspx

I have a piece of code to test this in practice in my WCF service:

    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;
    }

Furthermore, I have set the "Coins" Concurrency Mode in the model to "Fixed". However, this goes through and the value saved in the database is "1". I have tried with a few sets of values so it's not that it is "correct by accident". Why isn't an OptimisticConcurrencyException being raised here?

[update #1] By trying out the first response below and combining them, I managed to get a DbUpdateConcurrencyException out sometimes. It's still not the OptimisticConcurrencyException I am expecting but it is something. Basically I have no clue why it is not happening all the time.

            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.

Looks like there is a concurrency issue here!! :D

[update #2] Alright, I figured a part of it now and it was mostly stupid user error. DbUpdateConcurrencyException is thrown only once since second time, the second clause will update it to the value it is already in, so that part is logical. If two entities have been fetched from the same context, the latter change will simply be taken into account so in a "one database connection" case as suggested by the first response, no concurrency exception is raised. This is logical since it is up to the programmer to not access the object through multiple handles.

What I do not get though is the difference between DbUpdateConcurrencyException and OptimisticConcurrencyException. I have not being able to raise the latter.

4

2 回答 2

2

OptimisticConcurrencyException is from ADO.NET which underlies ADO.NET Entity Framework. The DbUpdateConcurrencyException is generated by Entity Framework. You shouldn't encounter an OptimisticConcurrencyException while using Entity Framework without using straight ADO.NET via a connection/command object.

于 2013-08-12T13:49:29.420 回答
0

I'm wonderung why you have created 2 connections to the database?!

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;
}
于 2013-08-12T13:17:23.833 回答