1

MySQL と Entity Framework を使用して ASP.NET / C# で webapp を開発しています。値を +1 ずつ増やして頻繁に更新されるいくつかのカウンター列を使用したいと考えています。カウンター列が存在する製品テーブルがあります。2 つの質問があります。

1) カウンター用に 2 つ目のテーブルを使用する必要がありますか? - メインの製品テーブルは頻繁に読み取られます。行を非常に頻繁に更新すると、カウンターが更新されるたびに行がロックされるため、パフォーマンスが低下する可能性があります (私は InnoDB を使用しています)。

2) MySQL と Entity Framework を使用して行を +1 インクリメントする最良の方法は何ですか? カウンターが 100% 正確であることは気にしないので、更新の競合があればキャッチできますが、更新なしで合格できます。ほとんどの更新は迅速に行われ、更新に含まれると思います。

これを実装するために使用しているコードを追加して、静的変数を利用してデータベースへの頻繁な書き込みを防ぎます。

コード:

if (Global.DataCounters != null)
    {
        if (Global.DataCounters.ContainsKey(id))
        {
            int new_value = ++Global.DataCounters[id];
            Global.DataCounters.Remove(id);
            Global.DataCounters.Add(id, new_value);

            // check datatime

            if ((DateTime.Now - Global.LastFlushed).Minutes > 10)
            {
                // update counter in db and reset data

                Global.LastFlushed = DateTime.Now;
            }
        }
        else
        {
            // first time view of a device, set to zero views
            Global.DataCounters.Add(id, 1);
        }

    }
    else
    {
        Global.DataCounters = new Dictionary<int, int>();
    }

Global.asax:

public static Dictionary<int, int> DataCounters = new Dictionary<int,int>();
public static DateTime LastFlushed;

void Application_Start(object sender, EventArgs e)
{
    LastFlushed = DateTime.Now;
    RegisterRoutes(System.Web.Routing.RouteTable.Routes);
}

いい実装だと思いませんか?

ありがとう

4

1 に答える 1

1

カウンターの 2 番目のテーブルは、重要な製品テーブルの読み取り (> 50% など) がカウンター情報を必要としない場合にのみ役立ちます。そうしないと、常に 2 つのテーブルを結合することになり、読み取りのコストが高くなります。

MySQL docに基づく: カウンターを更新する場合、WHERE 条件で一意のインデックスを使用して (更新する) 一意の行を検索すると、行レベルのロックのみが取得されます (ギャップ ロックは取得されません)。これは、あなたの場合に考えられる最良のシナリオです (製品 ID を一意のインデックスとして使用できると仮定します)。Entity SQL を使用して Update ステートメントを実行する (または同じことを行う SP を呼び出す) ことをお勧めします。

エンティティの用語のみ (EntitySQL または SP なし) で再生する場合は、この特定の操作にトランザクション スコープを使用しないでください。そのようにすると、製品エンティティを取得するための選択はロックされず、SaveChangesカウンターをインクリメントする単一の更新ステートメントになります。もちろん、トランザクションの外部で 2 つのステートメントを使用すると、更新が失敗する可能性があることを意味します (オプティミスティック コンカレンシー チェックに使用できるタイムスタンプ列があると仮定します) が、許容できることを示しています。

最後に、カウンタをインクリメントしている間にトランザクションが避けられない場合は、トランザクションを短くして、Read Committed.

于 2013-01-22T06:15:34.960 に答える