作爲註冊新用戶的一部分;我們從一個預編譯列表(一個表)中爲它們分配一個資源(在這種情況下是一個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