克隆一行做测试时,不要只改主键
集成测试要验证「新增一行能否同步到另一边」时,克隆已有数据必须改写全部唯一列。只换主键,插入仍然会因为业务唯一约束失败,测到的是重复键,不是同步链路。
背景与问题
典型报错是:
违反了 UNIQUE KEY 约束。不能在对象中插入重复键。
SELECT * INTO #clone 会把平台单号、业务流水号等唯一列原样复制。唯一索引拒绝第二行时,表面上看像同步没通或测试数据坏了,根因是克隆逻辑只改了主键。没有二级唯一索引的表上,只改主键能过;有业务单号的表上一定过不了。通用克隆若不处理唯一约束,测试会随机绿、随机红。
做法
插之前改写所有唯一列。单号可以换成测试前缀加新主键,长度不要超过列定义:
SELECT * INTO #clone FROM dbo.Orders WHERE Id = @src;
UPDATE #clone
SET Id = @newId,
Remark = @remark,
GlobalOrderNo = @uniqueBizKey; -- 业务唯一列也要换
INSERT INTO dbo.Orders SELECT * FROM #clone;
不同表的唯一列不一样。订单表可能有单号,发货表、采购表可能只有主键。克隆逻辑应按表名补这些列,或者查系统目录里 is_unique = 1 且不是主键的列,统一换成新值:
SELECT c.name
FROM sys.indexes i
JOIN sys.index_columns ic
ON ic.object_id = i.object_id AND ic.index_id = i.index_id
JOIN sys.columns c
ON c.object_id = ic.object_id AND c.column_id = ic.column_id
WHERE i.object_id = OBJECT_ID(N'dbo.Orders')
AND i.is_unique = 1
AND i.is_primary_key = 0;
测试插进去的行,业务库和报表库都要删。同步是异步的,断言完成后再删;失败路径放在 finally 里删,避免唯一键被测试数据占住,下一次运行还是同一条错误。
取舍与坑点
自动发现唯一列更通用,对计算列、含过滤条件的唯一索引、以及业务上唯一但库里没建索引的列仍会漏。按表维护一张「克隆时必改列」清单更可控,表结构变更时要同步更新。无论哪种,清理不彻底都会让下一次失败伪装成唯一键冲突。
结语
克隆测数时要把唯一约束当成和主键一样必须改写的字段,测的才是同步链路本身。
在Java集成测试中克隆数据库行验证同步链路时,仅修改主键会导致业务唯一约束(如平台单号、流水号)冲突,引发误判。正确做法是识别并改写所有非主键唯一列,如使用测试前缀+新主键生成新单号,并确保测试后彻底清理业务库与报表库数据。需权衡自动发现唯一列与按表维护必改清单的可靠性与可维护性。

332

被折叠的 条评论
为什么被折叠?



