我有一个mysql触发器,我注意到在几天前将触发器部署到生产站点后,我的数据库中出现了一些“未同步”的数据,并对此表示担忧。
为了在这里发布目的,我已经简化了我的代码。有三个表:
得分表: ID、UserID、Score、GameID(用户每次玩游戏时输入分数,他们可以玩同一款游戏多次)
得分摘要表: ID、UserID、GameID、SummaryValue(此表为每个用户和每个游戏保留了一个运行分数)
游戏摘要表: ID、GameID、SummaryValue(此表为每个游戏保留了一个总分数)
当用户将游戏得分输入得分表中时,触发器会更新得分摘要表中用户的运行总得分(SummaryValue),并更新给定GameID的game_summary表。
为了在这里发布目的,我已经简化了我的代码。有三个表:
得分表: ID、UserID、Score、GameID(用户每次玩游戏时输入分数,他们可以玩同一款游戏多次)
得分摘要表: ID、UserID、GameID、SummaryValue(此表为每个用户和每个游戏保留了一个运行分数)
游戏摘要表: ID、GameID、SummaryValue(此表为每个游戏保留了一个总分数)
当用户将游戏得分输入得分表中时,触发器会更新得分摘要表中用户的运行总得分(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更新 - 如果两个用户同时尝试这样做,他们都将得到rowCount = 0,然后都会进行插入?
我的担心是否合理?如果是,我能做些什么呢?
提前感谢大家。
ALTER TABLE game_summary ADD UNIQUE (gameId, categoryId, seasonId);
您真的应该考虑添加这样的键,因为即使在应用程序逻辑中出现错误,它也有助于保持数据一致性。 - Kamil Dziedzictimeout
秒后返回false。所以如果其他进程在timeout
之前释放锁,则会再次有机会获取锁。但是首先我仍然建议在一个或多个表列上使用一个唯一的键。 - Kamil Dziedzic