并发和锁

onlie 2007-05-21 05:40:30
我首先来讲一下我的大概情况
有一个订单,他的流水号是根据自定义的规则生成的

有一个表专门记录流水号的号段,表结构如下:
OrderSpan(订单区间)
OrderSpanId int /* 主键 identity */
BeginOrderId varchar(10) /* 开始号 */
EndOrderId varchar(10) /* 结束号 */
CurrentOrderId varchar(10) /* 当前的号 */
如数据: 1 2007000001 2007999999 2007000010
.....................................

还有一个表专门回收没有用到的号
UnUsedOrder(回收的订单)
UnUsedOrderId int /* 主键 identity */
OrderSpanId int /* 外键 */
OrderId varchar(10) /* 没有使用的订单 */

如数据: 1 1 2007000001
2 1 2007000002
................

最后一张是订单表,记录用户订单
Order(订单)
OrderId varchar(10) /* 主键 */
.......

其中 OrderId 是这样得来的:
首先查 UnUsedOrder(回收的订单表),如果该表有数据,那么则取其中最的最小的一个,再将该号从该表中删除.
如果UnUsedOrder(回收的订单表)中没有记录,那么就从OrderSpan(订单区间)读取CurrentOrderId,然后把CurrentOrderId=CurrentOrderId+1
用上面方法来生成OrderId,并插入到Order表中
在多用户情况下会产生重复的OrderId,请问怎么解决,谢谢!!!

...全文
249 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
onlie 2007-05-23
  • 打赏
  • 举报
回复
好的,我先试试。谢谢
jyxhz 2007-05-21
  • 打赏
  • 举报
回复
加排他锁
Yang_ 2007-05-21
  • 打赏
  • 举报
回复
写掉了更新单号代码

declare @OrderId varchar(10)
declare @src int

BEGIN TRAN
select @OrderId=min(OrderId),@src=1 from UnUsedOrder (TABLOCKX)
if @OrderId is null
select @OrderId=CurrentOrderId,@src=2 from OrderSpan (TABLOCKX) where 条件

if @OrderId is null
--找不到下一号码
goto err_Handle

insert Order(OrderId,...) values (@OrderId,...)
if @@error<>0
goto err_Handle

if @src=1
begin
delete UnUsedOrder where OrderId=@OrderId
if @@error<>0
goto err_Handle
end
else
begin
update OrderSpan
set CurrentOrderId=left(@OrderId,4)+right('000000'+rtrim(cast(right(@OrderId,6) as int)+1),6)
where 条件
if @@error<>0
goto err_Handle
end

COMMIT TRAN
return 0 --成功

err_Handle:
ROLLBACK TRANS
raiseerr ....
return 1 --失败
Yang_ 2007-05-21
  • 打赏
  • 举报
回复
写个存储过程来完成订单插入,大概如下

declare @OrderId varchar(10)
BEGIN TRAN
select @OrderId=min(OrderId) from UnUsedOrder (TABLOCKX)
if @OrderId is null
select @OrderId=CurrentOrderId from OrderSpan (TABLOCKX) where 条件

if @OrderId is null
--找不到下一号码
begin
ROLLBACK TRANS
raiseerr ....
return
end

insert Order(OrderId,...) values (@OrderId,...)
if @@error<>0
begin
ROLLBACK TRANS
raiseerr ....
return
end

COMMIT TRAN


Yang_ 2007-05-21
  • 打赏
  • 举报
回复
多用户下,必须用表锁才能保证不重号

两个表好像有点麻烦,事务变大了
onlie 2007-05-21
  • 打赏
  • 举报
回复
请按照我的需求来,请高手进
gahade 2007-05-21
  • 打赏
  • 举报
回复
先不要将编号取出来等待插入,先把数据插入,在表上建插入前触发器再获取编号.
cqq_chen 2007-05-21
  • 打赏
  • 举报
回复
使用系统自增做ID

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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