作为注册新用户的一部分;我们从预编译列表(表)中为它们分配资源(在本例中为 Solr 核心)。
如果 5 个用户注册,则必须为他们分配 5 个不同的核心;如果用户成功注册,分配即为最终分配(请参阅下面的描述)。
但在现实世界中,同时注册新用户竞争同一行,不选择不同行。如果X需要5秒来注册,则在X的“持续时间”内的Y和Z的注册将失败,因为它们与X争用同一行。
问题:即使在每秒100个注册的高并发下,如何让交易选择无争用?
table: User
user_id name core
1 Amy h1-c1
2 Anu h1-c1
3 Raj h1-c1
4 Ron h1-c2
5 Jon h1-c2
table: FreeCoreSlots
core_id core status
1 h1-c1 used
2 h1-c1 used
3 h1-c1 used
4 h1-c2 used
5 h1-c2 used #these went to above users already
6 h1-c2 free
7 h1-c2 free
8 h1-c2 free
9 h1-c2 free
如果东西被隔离,则伪代码:
sql = SQLTransaction()
core_details = sql.get("select * from FreeCoreSlots limit 1")
sql.execute("update FreeCoreSlots set status = 'used' where id = {id}".format(
id = core_details["id"]))
sql.execute("insert into users (name,core) values ({name},{core})".format(
name = name,
id = core_details["id"]))
sql.commit()
如果每秒有 100 个注册,他们会争夺第一排 in FreeCoreSlots
并造成严重故障。
有一个选择...用于更新,如下所示InnoDB SELECT ... FOR UPDATE 语句锁定表中的所有行 https://stackoverflow.com/questions/6690458/innodb-select-for-update-statement-locking-all-rows-in-a-table作为解决方案,但他们似乎建议降低隔离度。这种方法是正确的方法吗?