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