作为注册新用户的一部分;我们从一个预编译列表(一个表)中为它们分配一个资源(在这种情况下是一个Solr核心)。不同的交易必须保证选择不同的项目;避免争用
如果5个用户注册后,它们必须被分配5个不同的核;如果用户成功注册,那么分配将成为最终的(参见下面的描述)。
但在现实世界中,同时注册新用户争夺同一行,不选择不同的行。如果X需要5秒注册,Y和Z的注册这是在X的“期限”将作为他们争夺同一行的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 statement locking all rows in a table的解决方案,但他们似乎表明降低隔离。这种方法是否正确?
我认为这个例子不需要使用存储过程:http://stackoverflow.com/a/562744/1584772。至少,这是一个开始的好地方(关键是要让这一切都发生在一次交易中)。 – dan1111