流水号重复

叔到用时方恨嫂 2011-09-30 09:34:02
系统'保存'按钮事件里,通过sql语句获取max(预送单号),在其基础上加1,得到新的预送单号,现在系统有10几个人用,有时候同时‘保存’时会出现预送单号重复问题。有什么好的方法解决?
...全文
591 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
builderlzp 2011-10-09
  • 打赏
  • 举报
回复
提前取号不就是了,取号不用作废
丫丫的小脚丫 2011-10-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 xiaobn_cn 的回复:]
引用 6 楼 hefeng2011 的回复:
表已经有了自增列,想写个存储过程来控制。


这个解决方案要看你用的是什么数据库系统。
oracle:
定义一个预送单号的序列,使用该序列生成预送单号,可以保证并发时不会取重。

sql server:
将预送单号列设为自增列,由数据库自动维护该列的值。

[/Quote]
一般都是这方法
yingmu 2011-10-08
  • 打赏
  • 举报
回复
最简单的处理:每个用户端加个台号,自己生成自己的,呵呵。
jksby 2011-10-04
  • 打赏
  • 举报
回复
(1)在保存按钮中使用max+1获取最大号,保存,如果这个事务执行快,大并发量也不会重复。如果事务慢,你可以显式begin transaction,然后获取最大号,然后commit。
或者(2)数据库预送单号设计成自增序列
Cideason 2011-10-02
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qin_phoenix 的回复:]

有几百人同时使用的系统,使用这种办法,好像也没有遇到取号重复的问题啊!
[/Quote]

???? 什么方法?分享一下~~~
Cideason 2011-10-02
  • 打赏
  • 举报
回复
~~流水号重复主要原因是:

多用户提交或同时提交,因时间差的问题,存在还未提交成功的数据,

解决此问题:

关键是 取 多事务未提交成功数据+已经提交的数据(则是脏读)


如 :

sybase :
select max(sendno) from t_sendtable where 1=1 at isolation read uncommitted

MS SQL Server :
select max(sendno) from t_sendtable with(nolock) where 1=1
.

.

.

意思就是对流水号取值的表 脏读(未提交成功数据+已经提交的数据)取出对应的数据
这样 取出的数据做流水号跳号则不会重复的问题~~~~~~~~~~~

////////////////
qin_phoenix 2011-09-30
  • 打赏
  • 举报
回复
有几百人同时使用的系统,使用这种办法,好像也没有遇到取号重复的问题啊!
tqsxp 2011-09-30
  • 打赏
  • 举报
回复
新增单号表,每个提交用户都在表栏位的值上加1就ok了
  • 打赏
  • 举报
回复
表已经有了自增列,想写个存储过程来控制。
Samoon 2011-09-30
  • 打赏
  • 举报
回复
新号是在update的时候才生成的么?如果是的话,在这么短的传输时间内都能“同时”提交的话确实只能交给数据库处理了。用触发器或者带直接传带计算的sql给数据库。
yyoinge 2011-09-30
  • 打赏
  • 举报
回复
也可以用触发器来实现
yyoinge 2011-09-30
  • 打赏
  • 举报
回复
这种最好用自增列来控制,或者用专门的表来存储当前max单号值,然后通过锁表的方式取号
  • 打赏
  • 举报
回复
csdn来大姨妈了,发的技术帖子竟然404了。
  • 打赏
  • 举报
回复
csdn来大姨妈了,发的技术帖子竟然404了。
xiaobn_cn 2011-09-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 hefeng2011 的回复:]
表已经有了自增列,想写个存储过程来控制。
[/Quote]

这个解决方案要看你用的是什么数据库系统。
oracle:
定义一个预送单号的序列,使用该序列生成预送单号,可以保证并发时不会取重。

sql server:
将预送单号列设为自增列,由数据库自动维护该列的值。

其它数据库就不知道了,如果数据库不支持类似的功能可以采用以下方案自定义自增列:
1. 生成1个自增序列的表serial_table,表的结构为serial_name与serial_no
2. 插入记录,serial_name = 'ysdh',serial_no = 1 (如果不是从1开始就使用初始值)
3. 在需要生成预送单号的位置使用以下代码来获取序列号:
// 生成新的序列号并锁定
update serial_table set serial_no = serial_no + 1;
select serial_no into :ll_serialno from serial_table where serial_name = 'ysdh';

如果要使用存储过程取序列号得看你用的什么数据库,去相关板块学下怎么写存储过程就可以了,这个逻辑很简单的。

611

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder DataWindow
社区管理员
  • DataWindow社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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