專案中經常會用到自增id,比如uid,最簡單的方法就是用直接用資料庫提供的auto_increment,但是如程式設計客棧果使用者量非常大,幾千萬,幾億然後需要分表儲存的時候呢,這種方案就搞不定了,所以最好有乙個全域性的自增id的生成器,不管是否分表,都能從生成器中獲取到全域性自增的idilmzjnifeb。
實現方法應該有很多,不過所有的方案都需要解決乙個問題,就是保證在高併發的情景下,資料獲取依然正確,每次獲取的id都不會重複。
這裡我分享兩種利用mysql的innodb的事務特性來實現的方案,一種是實現過了的,另一種沒有試驗過,不過應該也能走的通。
先介紹第一種,在資料庫中單獨設定一張表,來儲存id,表有兩個字段,乙個是種類吧,乙個就是id:
複製** **如下:
create table auto_id(
idnwww.cppcns.comame varchar(20) not null default '',
id bigint(20) not null default 0 comment '',
primary key(idname)
)engine=innodb charset=utf8;
接下來是乙個儲存過程:
複製** **如下:
delimiter //
drop procedure if exists get_increment_idwww.cppcns.com;
create procedure get_increment_id(in idname_in varchar(20), in small_in bigint, out id_out bigint)
begin
declare oldid bigint;
start transaction;
select id into oldid from maibo_auto_id where idname=idname_in for update;
if oldid is null then
insert into maibo_auto_id(idname,id) value(idname_in, small_in);
set id_out=small_in;
else
update maibo_auto_id set id=id+1 where idname=idname_in;
set id_out=oldid+1;
end if;
commit;
end;
//
重點是這句,select id into oldid from maibo_auto_id where idname=idname_in for update,會給相關資料加乙個獨佔鎖定,這時候別的程序如果來讀取該條記錄,就會進入等待,等待這個程序commit之後,再繼續,這樣就保證了在併發的情況下,不同的程序不會取到相同的值。
如果你的前端是用php實現的。
只需執行如下兩個sql,就可以獲取到,這個small引數是定義的是從多少開始自增
複製** **如下:
$sql = "call get_increment_id('', , @id)";
$ret = $db->getdata("select @id");
還有另外一種方法,就是利用mysql的auto_increment。
先建立一張表,表裡邊只有乙個自增字段:
複製** **如下:
create table test(
`id` int(11) not null auto_increment comment 'id',
primary key (id)
)engine=myisam auto_increment=1 default charset=utf8;
通過如下兩條sql:
複製** **如下:
update test set id = last_insert_id(id + 1);
select last_insert_id();
也能解決問題, last_insert_id是不用查表的,而且只針對當前連線,也就是說別的連線的更新不會影響到當前連線的取值。
這樣可能每個id都得弄一張表來維護,這也是缺點。
具體使用中如何處理,就看自己的選擇了。
本文標題: 利用mysql事務特性實現併發安全的自增id示例
本文位址:
MySQL事務特性
目錄 什麼是事務?acid 原子性 atomicity 一致性 consistency 隔離性 isolation 永續性 durability 事務併發問題 事務隔離級別 一組原子性的sql指令集合,要麼全部執行成功,要麼全部執行失敗。整個事務所有操作要麼全部提交成功,要麼全部失敗回滾,不可能只成...
MySQL事務的特性
事務具有很嚴格的定義,必須同時滿足4個特徵 原子性 一致性 隔離性 永續性,也就是人們常說的acid標準 原子性,是指乙個事務必須被視為,乙個不可分割的最小工作單元,只有事務中所有的資料庫操作都執行成功,才算整個事務執行成功 事務中,如果有任何乙個sql語句執行失敗,已經執行成功的sql語句,也必須...
MySQL 事務和特性
事務是資料庫操作的最小工作單位,乙個事務可以是一條sql語句,也可以是一組sql語句。事務有四大特徵 原子性,永續性,隔離性,一致性,就是我們常說的acid 原子性的意思是說乙個事務裡的操作會組成乙個最小的執行單位,不可再分割,在乙個事務中,要麼操作都成功,要麼都失敗。比較經典的例子就是我們的轉賬,...