处理并发SQL插入的正确实现是什么,同时确保非主键列(即wid)唯一且自动增量?

时间:2015-07-27 09:12:54

标签: mysql database transactions

在确保非主键列(即wid)唯一且自动增量的同时处理并发SQL插入的正确实现是什么?

注意:有一个设计约束导致该字段(即wid)不成为主键。名为id的列中包含单独的自动增量PK。将wid更改为PK是不可行的,因为数据库设计现在与多个软件项目紧密耦合。所以我需要设计一种解决方法。

我想到了3种可能的方法:

1。)通过执行事务并继续处理应该包含在同一事务中的其他SQL语句来保留wid。保留在单独的事务中执行,以使锁定尽可能短。但是,如果后续事务失败(例如由于数据库连接问题),则包含保留wid的无效行将保留在表中。

START TRANSACTION;
SET @wid_d = 0;
SELECT COALESCE(MAX(`wid`), 0) INTO @wid_d FROM table
WHERE `wid >= 0 AND `wid <= 1000 FOR UPDATE;
INSERT INTO table (`wid`) VALUES (IF (@wid_d = 0, 1, @wid_d+1) )
COMMIT;

2。)包括在整个事务中保留wid以消除插入无效行的问题,如果事务失败但这种方法会延长表的锁定。

3。)依靠事务调用失败重新执行事务直到它成功执行;如果由于插入相同MAX(wid)+ 1的竞争条件而导致事务失败。这种方法将阻止插入无效行,但问题是应该重新运行事务的次数。知道由于冲突的wid或其他问题引起的问题也没有区别,因此,这是一个有问题的方法。

1 个答案:

答案 0 :(得分:1)

那么,根据您的勇敢程度,您还有其他选择,例如创建将用于维护WID值的单独序列表:

CREATE TABLE wid_seq (wid INT PRIMARY KEY AUTO_INCREMENT);

并在您的交易中:

START TRANSACTION;
INSERT INTO wid_seq VALUES (null);
INSERT yourtable (WID) values (LAST_INSERT_ID());
COMMIT;