0

私のC#プロジェクトには、データベースにオブジェクトが存在するかどうかを尋ね、存在しない場合はそれを作成するメソッドがあります。ここで、2 人のユーザーが同時に同じ質問をすると、両方とも null になるため、フローは db に保存されますが、2 つの重複がそれを行うことは不可能であるため、SQL 例外が発生します。どうすればこの問題に対処できますか?

ここに私のコードがあります:

var date = DateTime.UtcNow.Date;


var todayCelebPageView = _celebPageViewsRepo.GetAll().SingleOrDefault(d => d.iCelebId == celebId && d.dDate == date);

if (todayCelebPageView != null)
{
    todayCelebPageView.iScore++;

    _celebPageViewsRepo.Save();
}
else
{
    todayCelebPageView = new MovliCelebPageView() {dDate = date, iCelebId = celebId, iScore = 1};
    _celebPageViewsRepo.Add(todayCelebPageView);
    _movliRepository.DbContext.Entry(todayCelebPageView).State = System.Data.EntityState.Added;
    _celebPageViewsRepo.Save();
}
4

3 に答える 3

2

これに対する簡単な答えはありません。多くのソリューションに共通する問題です。

いくつかのオプションは次のとおりです。

  1. 正しい SQL 例外をキャッチし、それに応じて再試行します
  2. これらのデータベース呼び出しのキューを作成し、一度に 1 つずつ処理します
  3. データベース(おそらくトランザクションでラップすることによる)またはコード自体でのロックの実装。

他に考慮すべきことは、レコードの作成が同時に 2 回試行された場合に、ビジネスの観点から何が起こるべきかということです。

最後に記録を作成した人が勝つべきですか? 最初の人が勝ち、2 番目の人がエラーを受け取るべきですか? それとも、最初のレコードを書き込んで、2 番目のレコードで再度更新する必要がありますか?

これに対する答えは、アプリケーションで何をしようとしているかの詳細に完全に依存します。

于 2015-04-14T08:36:23.710 に答える
0

チェックと作成のロジックをプロシージャ レベルに移動すると、トランザクション分離で処理されます。

IF NOT EXISTS (SELECT 'non-empty' FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.TABLE_NAME') AND type in (N'U'))
    CREATE TABLE dbo.TABLE_NAME

Numberただし、次のプロパティに従ってメソッドをラップし、例外を処理する必要がありますSqlException

using (SqlConnection connection = new SqlConnection(connectionString))
{
    SqlCommand command = new SqlCommand(queryString, connection);
    try
    {
        command.Connection.Open();
        command.ExecuteNonQuery();
    }
    catch (SqlException ex)
    {
        for (int i = 0; i < ex.Errors.Count; i++)
        {
            errorMessages.Append("Index #" + i + "\n" +
                "Message: " + ex.Errors[i].Message + "\n" +
                "LineNumber: " + ex.Errors[i].LineNumber + "\n" +
                "Source: " + ex.Errors[i].Source + "\n" +
                "Procedure: " + ex.Errors[i].Procedure + "\n");
        }
        Console.WriteLine(errorMessages.ToString());
    }
}

システム エラー メッセージ
データベース エンジン エラーの原因と解決策

于 2015-04-14T08:36:27.300 に答える
0

トランザクションの存在と挿入のテストをラップする必要があります。このようにして、存在を確認するための 2 番目の呼び出しは、最初の呼び出しが完了している間にブロックされます。

于 2015-04-14T08:36:36.100 に答える