【发布时间】:2015-03-01 03:07:44
【问题描述】:
我有这种结构的表:
CREATE TABLE IF NOT EXISTS `message` (
`id` bigint(20) NOT NULL,
`appKey` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
`text` text COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
和主键(id,appKey)
我想为每个 appKey 独立地设置 id 自动增量。所以我使用触发器。
CREATE TRIGGER `messageId` BEFORE INSERT ON `message`
FOR EACH ROW begin
declare v_messageId bigint(20) unsigned default 0;
SELECT max(id) INTO v_messageId FROM message WHERE appKey = new.appKey;
if (v_messageId IS NULL) THEN
set v_messageId=0;
end if;
SET new.id=v_messageId + 1;
end
在我尝试从两个数据库连接(我在应用程序中使用连接池)同时插入两行之前,它工作正常。插入第一行。但第二次抛出错误 ER_DUP_ENTRY: Duplicate entry '18-secretkey' for key 'PRIMARY'。
我知道为什么会这样。我的问题是:MySQL 是否可以完成这项任务,或者我必须使用不同的数据库(可能是 PostgreSQL,因为咨询锁)?
编辑:
在表中我有这些行:
编号 |应用密钥 |文本 ---+--------+------------ 1 |键 1 |某物 2 |键 1 |某物 1 |键 2 |某物 2 |键 2 |某物 3 |键 1 |某物错误是在我尝试插入这两行之后:
应用密钥 |文本 --------+------- 键1 |某物 键1 |某物【问题讨论】:
-
dev.mysql.com/doc/refman/5.1/en/example-auto-increment.html 使用内置工具。使用 max(ID) 加 1 对竞态条件的异常处理非常令人头疼
-
@xBert 我猜你不明白我的问题。我编辑了问题。
-
从上面的链接,“MyISAM 注释 对于 MyISAM 表,您可以在多列索引中的辅助列上指定 AUTO_INCREMENT。在这种情况下,AUTO_INCREMENT 列的生成值计算为 MAX( auto_increment_column) + 1 WHERE prefix=given-prefix。当您想将数据放入有序组时,这很有用。如果这不是你想要做的,我真的不明白你的问题。
-
@xQbert 我正在使用 InnoDB 引擎,无法使用 MyISAM。这就是我尝试使用触发器解决此问题的原因。
-
不知道为什么我错过了那个语法... sorr.y
标签: mysql triggers auto-increment