作为注册新用户的一部分;我们从预编译列表(表)中为它们分配资源(在本例中为 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 次注册,他们将争夺第一行并FreeCoreSlots
导致严重失败。
有一个 select... for update 如InnoDB SELECT ... FOR UPDATE 语句锁定表中的所有行作为解决方案,但他们似乎建议降低隔离。这种方法正确吗?