我想在一个事务请求中执行对数据库进行读取和条件创建或更新。
让我们以暴雪的星际争霸游戏为例: 假设Bob想要与其他随机玩家进行决斗。 他只需点击“搜索按钮”,然后在查询其数据库后,服务器将创建一个与Bob相比较的新游戏,例如Alice。
在此示例中,假设数据库包含users
和games
个表。
这种情况可能发生在以下步骤:
games
(src_user
FK添加到Alice,dst_user
FK到NULL
)添加新行。 dst_user
FK可以从NULL
切换到Bob。这个系统似乎很好。但我担心的是,由于用户数量庞大,如果搜索和更新都不是原子的,可能会同时进行更新。
我的意思是,如果同时Bob和Oscar正在寻找游戏,那么SQL服务器首先会为两个用户回答Alice的游戏请求(这是games
表中的一行)。然后,鲍勃和奥斯卡都会尝试更新这条线以加入游戏。
为了防止这种情况,是否可以在一个查询中处理所有这些(如果可能的话,保持与MySQL和PostgreSQL的兼容性)?
PS:数据库结构可能就是这个......
CREATE TABLE users (
id SERIAL PRIMARY KEY,
);
CREATE TABLE games (
id SERIAL PRIMARY KEY,
src_user_id BIGINT UNSIGNED NOT NULL,
-- if NULL, the game is not ready...
dst_user_id BIGINT UNSIGNED NULL,
FOREIGN KEY (src_user_id) REFERENCES users(id),
FOREIGN KEY (dst_user_id) REFERENCES users(id)
);
答案 0 :(得分:1)
我使用这样的查询:
update games set dst_user_id=? where id=? and dst_user_id is null;
这样我可以确保只有在没有其他用户加入时才会更新行。要检查游戏是否成功创建,我要检查更新的行数 - 大多数数据库引擎都支持此行。