You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何原子性插入特定前缀对应的唯一序号客户编码记录?

并发场景下客户编码原子性插入解决方案

方案1:使用数据库原生序列(推荐)

多数现代数据库(SQL Server、PostgreSQL、Oracle等)都支持独立的序列生成器,能原生保证并发环境下的序号唯一性,彻底避免约束冲突。

以SQL Server为例,先为每个CodePrefix创建专属序列:

-- 为WIP前缀创建序列,初始值1,步长1
CREATE SEQUENCE Seq_CustomerCode_WIP
    START WITH 1
    INCREMENT BY 1;

插入时直接调用序列获取下一个值:

INSERT INTO CustomerCodes (CustomerId, CodePrefix, Ordinal)
VALUES (1, 'WIP', NEXT VALUE FOR Seq_CustomerCode_WIP);

如果需要适配多个前缀,可提前为所有可能的前缀创建序列,或用动态SQL生成序列调用语句。

方案2:用辅助计数器表+UPSERT实现锁机制

如果数据库不支持序列,可创建一个辅助表维护各前缀的当前最大序号,通过UPDATE的行级锁保证并发安全:

  1. 先创建辅助表:
CREATE TABLE CustomerCodeCounters (
    CodePrefix VARCHAR(3) PRIMARY KEY,
    CurrentOrdinal INT DEFAULT 0
);
  1. 原子性插入逻辑(含事务):
BEGIN TRANSACTION;

-- 更新对应前缀的计数器,行锁会阻塞其他并发事务
UPDATE CustomerCodeCounters
SET CurrentOrdinal = CurrentOrdinal + 1
WHERE CodePrefix = 'WIP';

-- 若该前缀无记录,初始化计数器
IF @@ROWCOUNT = 0
BEGIN
    INSERT INTO CustomerCodeCounters (CodePrefix, CurrentOrdinal)
    VALUES ('WIP', 1);
END

-- 获取新序号
DECLARE @NewOrdinal INT;
SELECT @NewOrdinal = CurrentOrdinal FROM CustomerCodeCounters WHERE CodePrefix = 'WIP';

-- 插入客户编码
INSERT INTO CustomerCodes (CustomerId, CodePrefix, Ordinal)
VALUES (1, 'WIP', @NewOrdinal);

COMMIT TRANSACTION;

方案3:添加锁定提示(轻量临时方案)

无需额外建表,在查询最大序号时添加UPDLOCK, HOLDLOCK提示,强制锁定目标记录范围,直到事务结束:

BEGIN TRANSACTION;

DECLARE @NewOrdinal INT;
SELECT @NewOrdinal = ISNULL(MAX(Ordinal), 0) + 1
FROM CustomerCodes WITH (UPDLOCK, HOLDLOCK)
WHERE CodePrefix = 'WIP';

INSERT INTO CustomerCodes (CustomerId, CodePrefix, Ordinal)
VALUES (1, 'WIP', @NewOrdinal);

COMMIT TRANSACTION;

UPDLOCK为符合条件的记录添加更新锁,HOLDLOCK将锁的持有时间延长至事务提交,确保其他事务无法同时读取并生成重复序号。

内容的提问来源于stack exchange,提问作者Michael P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:20:32