插入DB时取得主键冲突问题

游北亮
博客专家认证
2007-03-06 04:39:53
问题是这样的,我设置了一个数值型字段为主键,新记录主键是旧记录最大主键加1
SQL这么写会报错:
"insert into [log] (id,userId) values((select max(id)+1 from [log]),'" + loginUser + "')"

后来就改成先在C#中取得主键并加1,然后再插入数据库
执行 id = (select max(id)+1 from [log])
然后"insert into [log] (id,userId) values(" + id + ",'" + loginUser + "')"
这样在多个页面同时打开时,可能造成主键重复

现在改写SQL为下面,正常了:
"insert into [log] (id,userId) select max(id)+1,'" + loginUser + "' from [log]"

请问除了上面的办法还有什么更好的办法没有?
不使用自动增长的字段。
...全文
384 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
游北亮 2007-03-08
  • 打赏
  • 举报
回复
顶一下
sp1234(疯投来了,原来也是空手套白狼)?
能否请教你的高见
游北亮 2007-03-07
  • 打赏
  • 举报
回复
sp1234(全面扫描了一下机器,发现20只木马程序)
谢谢你的解释,这个主键一是可以作索引,二也用来排序,以判别记录入库的先后顺序
所以使用GUID是不行的。
游北亮 2007-03-07
  • 打赏
  • 举报
回复
Snowdust(雪尘)
你的方法还是会冲突,比如插入之前去查找主键值,找到后的瞬间,另一进程更新了这个键值(加1),那么之前得到的键值加1,就会冲突了。

sp1234(全面扫描了一下机器,发现20只木马程序)
程序中无法使用事务处理。
游北亮 2007-03-07
  • 打赏
  • 举报
回复
这套程序要用在多个数据库上,所以不能用数据库的特殊类型,除了这个表,其它表都是在程序中生成GUID,使用GUID作主键,但是这个表要区分入库的先后顺序
foxfoxfoxchen 2007-03-07
  • 打赏
  • 举报
回复
问下,为什么不直接用数据库里的唯一标识呢?
游北亮 2007-03-07
  • 打赏
  • 举报
回复
哦,流水号只要简单的ORDER BY DESC,不就可以了吗?
如果用时间字段,可能会有重复的时间

还有什么其它的好方法方便的判别记录入库顺序吗?

而且这个程序不存在重排流水号等操作。
  • 打赏
  • 举报
回复
哎,其实技术纠缠总在人自己是不愿意多做一点点。

好的,我就再按你的思路多问一点点:你根据什么说排序必须用主键?
  • 打赏
  • 举报
回复
不过,使用事务是一种性能极其低下的做法。如果可能,不要将主键设计为流水号。反过来说,不要将流水号假想为数据库主键。

数据库主键应该使用一种与任何业务概念无关的方法来设计。例如GUID类型的值,在SQL Server中是uniqueidentifier。

而流水号有逻辑意义。其实流水号完全可以在记录已经产生之后再产生,也可以随时修改,例如前边某个流水号被删除的时候需要重新编排流水号。很多时候也不产生流水号,而是用排序字段和序号到记录集合里从往后遍历。

总之把流水当作数据库主键,是非技术人员制造的技术困难。
  • 打赏
  • 举报
回复
Q: 这样在多个页面同时打开时,可能造成主键重复

A: 你在这个操作前后,应该明确地打开Transanction对象。
Snowdust 2007-03-06
  • 打赏
  • 举报
回复
将表、表当前ID值放入一张表(比如A)中,再使用存储过程插入,插入之前先去查A表,插入成功后再把A表中“值”字段加1。
表的内容如下(示例):
表名 主键字段名 值
table1 table1_ID 1
table2 table2_ID 49
table3 table3_ID 0

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧