萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 利用事務特性實現高併發安全的全局自增 ID 生成器

分表分庫架構下需全局唯一自增 ID。利用 InnoDB 行鎖 (SELECT ... FOR UPDATE) 或 LAST_INSERT_ID() 可實現無鎖高併發 ID 生成。本文提供兩種方案完整 SQL 與 PHP 調用範例。

方案一:單表 + 存儲過程 + 行鎖 (推薦)

CREATE TABLE auto_id (
    idname VARCHAR(20) NOT NULL DEFAULT '',
    id BIGINT(20) NOT NULL DEFAULT 0,
    PRIMARY KEY (idname)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DELIMITER //
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 auto_id WHERE idname=idname_in FOR UPDATE;
    IF oldid IS NULL THEN
        INSERT INTO auto_id(idname,id) VALUES(idname_in, small_in);
        SET id_out = small_in;
    ELSE
        UPDATE auto_id SET id=id+1 WHERE idname=idname_in;
        SET id_out = oldid+1;
    END IF;
    COMMIT;
END//
DELIMITER ;

PHP 調用:CALL get_increment_id('key', 1000, @id); SELECT @id;

方案二:利用 AUTO_INCREMENT + LAST_INSERT_ID (無需存儲過程)

CREATE TABLE test_id (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE=MyISAM;

-- 獲取下一 ID
UPDATE test_id SET id = LAST_INSERT_ID(id + 1);
SELECT LAST_INSERT_ID();

LAST_INSERT_ID() 為連接級變數,天然線程安全,但每種 ID 需一張表。

選型建議

  • 方案一:單表維護多業務 ID,靈活、擴展性強。
  • 方案二:極簡、無鎖、適合單一 ID 序列。
copyright © 萬盛學電腦網 all rights reserved