5

数日前に本番サイトにトリガーをデプロイした後、データベース内の「同期されていない」データに気付いたという懸念があるmysqlトリガーがあります。

ここに投稿するために、コードを簡略化しました。

3つのテーブルがあります:

スコアテーブル:ID、UserID、Score、GameID(ユーザーはゲームをプレイするたびにスコアを入力します。同じゲームを何度もプレイできます)

score_summaryテーブル:ID、UserID、GameID、SummaryValue(このテーブルは、各ゲームの各ユーザーの実行スコアを保持します)

game_summaryテーブル:ID、GameID、SummaryValue(このテーブルは各ゲームの実行中の全体的なスコアを保持します)

ユーザーのゲームスコアがスコアテーブルに入力されると、トリガーは、テーブルscore_summary内のユーザーの現在の合計スコア(SummaryValue)を更新し、指定されたGameIDのgame_summaryテーブルを更新するためにあります。

CREATE TRIGGER scores_insert_trigger AFTER INSERT ON scores
FOR EACH ROW BEGIN

    UPDATE scores_summary
    SET SummaryValue=SummaryValue + NEW.Score 
    WHERE UserID=NEW.UserID
    SELECT ROW_COUNT() INTO rowCount;
    IF (rowCount=0) THEN
        INSERT INTO scores_summary
        (UserID, GameID, SummaryValue)
        VALUES
        (NEW.UserID, NEW.GameID, NEW.Score);
    END IF;

    UPDATE game_summary
    SET SummaryValue=SummaryValue + NEW.Score 
    WHERE GameID=NEW.GameID
    SELECT ROW_COUNT() INTO rowCount;
    IF (rowCount=0) THEN
        INSERT INTO game_summary
        (GameID, SummaryValue)
        VALUES
        (NEW.GameID, NEW.Score);
    END IF;
END;

私の懸念は、複数のユーザーが同時にスコアを入力した場合、特に特定のゲームのスコアが存在しない場合のgame_summaryの更新の場合、2人のユーザーが同時にこれを試みた場合に、競合状態に陥るトリガーに関するものです。時間、それらは両方ともrowCount = 0を取得し、次に両方とも挿入を行いますか?

私の懸念は正当化されていますか?もしそうなら、これについて私ができることはありますか?

よろしくお願いします。

4

2 に答える 2

1

UNIQUEインデックスを作成するgame_summary.GameIDか、主キーにします。

UNIQUEindexは、2番目のユーザーによる重複行の追加を防ぎます。トランザクション全体が失敗し、ロールバックされるため、アプリケーションはこの例外を処理する必要があります。たとえば、失敗した後は、あきらめる前に再試行してください。このソリューションの欠点は、非常にビジーな環境では、多くの衝突と多くのロールバックが発生することですが、重複する行がないことを確認できます。

GET_LOCK(str、timeout)関数を使用して、指定された値の排他的ロックを取得しGameID、値を更新または挿入し、最後にRELEASE_LOCK(str)を使用して、次のユーザーもスコアを更新できるようにすることもできます。これは状況によってははるかに効率的かもしれませんが、それを確認する必要があります。

于 2012-12-14T17:16:09.043 に答える
0

私の特定の状況に対する答えを提供したいと思います。

私の更新ステートメントはアトミック更新です。これは、mysqlエンジンが潜在的な競合状態を処理することを意味します。

挿入時の競合状態を回避するために、ON DUPLICATE KEY UPDATEを選択しました。これもアトミックであり、2つ以上のスレッドによって複数の行が作成されるのを回避します。

ご協力いただきありがとうございます。

于 2013-01-04T00:12:00.733 に答える