names
是每一個獨特的名稱映射到一個ID表:添加到或唯一鍵的SQL表中檢索和值
CREATE TABLE names (
name VARCHAR(20) NOT NULL,
name_id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (name),
UNIQUE (name_id)
) ENGINE=InnoDB
如果「foobar的」已經存儲在names
,我想其name_id
。否則,我想存儲它並獲取爲其生成的name_id
。
如何做到這一點,處理兩個線程競爭加入'foobar'的可能性? (注:我們從來沒有從該表中刪除。)
於MyISAM我寫道:
GET_LOCK('foobar');
SELECT name_id FROM names WHERE name = 'foobar';
if name wasn't found
INSERT INTO names SET name='foobar';
SELECT LAST_INSERT_ID(); -- that is, name_id
RELEASE_LOCK('foobar');
但是,我對如何實現這一目標使用事務和行級鎖定在InnoDB中非常不清楚。
更新: mySQL要求AUTO_INCREMENT僅用於PK。我正在使用MariaDB,它只需要將AUTO_INCREMENT列定義爲鍵。相應地更新示例。
用'START TRANSACTION'和'COMMIT'替換'GET_LOCK'和'RELEASE_LOCK'。 – Barmar
@Barmar當第二個線程執行INSERT並獲得DUPLICATE KEY違例時會發生什麼?或者是第二個線程在START TRANSACTION被阻止,直到第一個線程結束交易? – Chap
我認爲應該阻止第二個線程。但嘗試一下,看看。 – Barmar