MySQL并发获取自增值的测试及处理

思考及测试

基本设定

数据库需要使用自定义的自增值。
用GUID浪费资源,大家测试一下取10000条记录时,返回GUID与使用数据库10000的自增值比较就懂了,这个场景多出现在导入Excel或其他情况,使用自增值时,可以一次性生成一个数值段,避免了重复生成。
使用MySQL自增字段会导致在数据库中最后插入数值的ID大于规划的ID时,无法从规划的ID进行自增,这个对分布式多数据库影响很大。

解决计划

使用MySQL提供锁,如下所示:

select * from auto_id for update;

首先,让我们建一个表

CREATE TABLE `auto_id` (
	`idname` VARCHAR(30) NOT NULL DEFAULT '',
	`id` BIGINT(20) NOT NULL DEFAULT '0',
	PRIMARY KEY (`idname`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;;

插入一条记录

insert into auto_id (idname, id) values('abc', 0);

测试自增锁

打开两个工具分别运行:

select * from auto_id for update;
update auto_id set id = id + 1 where idname = 'abc';
select * from auto_id;

这个测试的两个客户端都自增了,并不能说明自增是正确的,这是为什么呢?原因很简单,这是因为:MySQL的默认级别是:REPEATABLE-READ,意思是说只要Update就会马上提交,因此无法测试我们的结果,因此我们应该把测试脚本修改为:

start transaction;
select * from auto_id for update;
update auto_id set id = id + 1 where idname = 'abc';
select * from auto_id;

原理很简单,先对其进行锁处理,然后再进行Update,在select中使用for update,这时会发现测试窗口A中的记录执行成功了,测试窗口B的脚本,运行到 select * from auto_id for update; 就运行不下去了,这说明锁起了作用,当并发产生时,未能进入锁操作的事务被挂起了。这时,只需要在窗口A中运行commit,窗口B的脚本就可以运行下去了。

结论

使用事务与for update语句来处理MySQL的并发问题是可行的

最终解决脚本

存储过程代码

CREATE PROCEDURE `p_sys_get_increment_id`(
	IN `idname_in` VARCHAR(20),
	IN `count_in` BIGINT,
	OUT `id_out` BIGINT
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT '取自增ID'
BEGIN
	declare oldid bigint;
	
	start transaction; 
	select id into oldid from auto_id where idname=idname_in for update; 
	
	if oldid is NULL then 
		insert into auto_id(idname, id) value(idname_in, count_in + 1); 
		set id_out = 1;
	else 
		update auto_id set id = id + count_in where idname = idname_in; 
		set id_out = oldid; 
	end if;
	
	commit;  
END

测试

call p_sys_get_increment_id('abc', 10000, @key);
select @key;

结果非常快,达到之前设定的目标

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值