生成每日唯一序号的难题

iamtsfw 2014-01-02 06:46:24
使用的数据库是sql server 2000

使用vb做了一个c/s程序,程序中有一个添加按钮,每当按这个按钮的时候,就会调用存储过程执行如下操作:(通常仅仅有操作员A使用这个添加按钮,其他人看不到这个按钮)
1 从表中挑选当日最大序号,假设最大序号是201312120010,序号永远为12位,每日从0001至9999。
2 将0010取出来转为浮点数后加1,得到11。
3 把11转换为0011后与日期拼起来,例如201312120011。
4 将201312120011插入数据库。
5 取回这个201312120011,然后显示给客户。
与此同时:
1 可能会有人在更新序号为非201312120010的序号的数据。
2 可能有人在汇总包含201312120011这个序号的表的数据。

在不知道其他客户端都在做什么的情况下:
操作员A使用添加按钮时,偶尔会发现新添加的序号还是上个序号,真是活见鬼了,这种情况是完全不能容忍的,会造成非常严重的后果。
试问高手,这种情况是如何产生的?如何解决?


...全文
260 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
allanli 2014-01-05
  • 打赏
  • 举报
回复
引用 21 楼 iamtsfw 的回复:
实在没招了,只能用主键设置了。
我觉得你应该在程序层面做一个错误捕捉,看看到底产生重复的时候是那个用户在那台电脑操作的,与那个用户在那台电脑生成的序号重复(这个可以做一个日志表记录每个单号是那个用户在那台电脑产生的) 这样就好跟踪原因了,我觉得你这个问题不外乎两种可能,一个是两个连接同时产生了单号(你说只有一个用户有权限,但你能否确定不会产生这个用户在不同电脑同时登陆呢) 二者就是同一个用户在同一台电脑产生了重复单号,是程序有Bug造成(很多时候往往自己认为没可能的东西都是因为程序逻辑错误造成的,这个我遇到不少,呵呵) 这类问题只可能是人为造成的,不可能是机器错误,因为电脑是不会错的,错的都是你的指令错而已
hgwyl 2014-01-05
  • 打赏
  • 举报
回复
可能有人在汇总包含201312120011这个序号的表的数据 ——这里表示这个12位数字,是可能存在于多条数据中,属于“1对多”的关系。不可能设置为主键。
hgwyl 2014-01-05
  • 打赏
  • 举报
回复
楼主说说实际业务 没看出来这个12位数字有什么用,所以无法分析解决办法
iamtsfw 2014-01-04
  • 打赏
  • 举报
回复
实在没招了,只能用主键设置了。
haitao 2014-01-03
  • 打赏
  • 举报
回复
一般情况(并发性没那么大)可以:
declare @m int
select @m=isnull(right(max(dayid),4),1) from xxx where left(dayid,8)='今日如20140103'
set @m=@m+1
insert xxx (dayid,...) values (@m,...)

如果高一点的版本
使用 update ... output ... 比较保险
iamtsfw 2014-01-03
  • 打赏
  • 举报
回复
我修改了存储过程: 首先:把1 2 3步合并为一个语句,直接挑选出最大序号,然后加1,然后返回新最大序号 其次:把这个语句中from 某表 where ... 改为from 某表 with (updlock) where... 再次:以前是1 insert 2 select 最大序号 3 提交事务 现在改为1 insert 2 提交事务 3 select 最大序号 第四:以前是生成序号后,再挑选出一部分需要同时插入的数据,与最大序号一起insert,现在改为,进入存储过程就先挑选。 测试中...
Yole 2014-01-03
  • 打赏
  • 举报
回复
可以把这个号放在表中,然后去维护新的表的最大编号字段,每次取数都从这个最大编号上加1. 写一个存储过程去调用,每次都用过程取数!
發糞塗牆 2014-01-03
  • 打赏
  • 举报
回复
个人观点: 1、你的第二步,为什么转成浮点而不是整型?没必要考虑精度问题吧? 2、有人插入,有人更新,那么隔离级别就需要考虑了。 3、你实在不能理解的话,把sql trace开启一段时间,然后累一点,周期性监控一下数据,比如10分钟一次,看看大概什么时间发生了重复,然后再从trace文件中检查那个时间段的语句。不过想一想这一步的确很累,所以只是最终做法
tcmakebest 2014-01-02
  • 打赏
  • 举报
回复
从楼主的描述看基本没有问题,可能是写的代码质量不行.
专注or全面 2014-01-02
  • 打赏
  • 举报
回复
可能是你生成序号的存储过程的问题?贴出来看看
giftzheng 2014-01-02
  • 打赏
  • 举报
回复
加一个自增字段 去观察序号与自增id规律,表关联用自增id 201312120010这样的序号 弄一个别的表去自维护 你点添加按钮的时候在这个表生成201312120010
  • 打赏
  • 举报
回复
另外,这个表中的需要是否会被删除呢
  • 打赏
  • 举报
回复
会不会是误操作
  • 打赏
  • 举报
回复
引用 10 楼 iamtsfw 的回复:
存储过程非常简单,并发时肯定会有问题,我也知道。 令人困惑的是:只有一个人在做这个添加操作啊,怎么还会生成重复的序号?
会不会是用户,点了两次
iamtsfw 2014-01-02
  • 打赏
  • 举报
回复
存储过程非常简单,并发时肯定会有问题,我也知道。 令人困惑的是:只有一个人在做这个添加操作啊,怎么还会生成重复的序号?
iamtsfw 2014-01-02
  • 打赏
  • 举报
回复
如果是一台计算机操作,从来不会发生这种情况,接入多个客户端之后才发生的这种问题,所以我想一定是与其他客户端的操作有关,但是接入了20多个客户端后,不知道其他人在做什么,所以让人非常困惑,难以解决。同时这个错误在2个月内只发生了8次,无法每天实时监测,真的希望有遇到过这种情况的同志们给出其他解决思路。
  • 打赏
  • 举报
回复
因为就像你上面说的,从表面分析这个存储过程的流程,完全没问题,那么到底是哪个代码出了问题,最好是能掌握一定的数据,否则凭空猜测,最后也解决不了问题
  • 打赏
  • 举报
回复
引用 6 楼 iamtsfw 的回复:
最后这个回答与我当前的思路相同: 我当前的解决方案就是把这个序号字段设置为主键,然后出现序号重复后客户端会报错,让操作员A重新添加一次。 但感觉这不是最佳方案,是实在没招了,把错误放给数据库去处理了,能否有更佳方案呢?
嗯,确实是这样,不一定要设置为主键,设置一个unique也可以,不过这个确实是没办法的办法。 现在的主要问题是,不知道问题在哪里,所以要想彻底解决这个问题,首先得找到问题的原因所在,就是要重现这个问题。 最好修改一下你的存储过程,做个错误处理,记录下,错误发生时候,各种变量的值,然后记录到某个表中,便于,收集错误信息,然后再进行分析。
iamtsfw 2014-01-02
  • 打赏
  • 举报
回复
最后这个回答与我当前的思路相同: 我当前的解决方案就是把这个序号字段设置为主键,然后出现序号重复后客户端会报错,让操作员A重新添加一次。 但感觉这不是最佳方案,是实在没招了,把错误放给数据库去处理了,能否有更佳方案呢?
  • 打赏
  • 举报
回复
这个序号是不是主键把,或者是没有唯一约束的把,要不给建个唯一约束,这样,如果插入的是重复值,那么就报错,至少可以保证不再插入重复值了。
加载更多回复(4)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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