我实在想不出是什么原因,请教各位朋友!!!

时间:2022-09-20 23:27:51
B/S结构的系统!有一存储过程要实现的是
生成随机定单号,格式是:日期+3位随机数
同时生成一个8位数字的密码和特定格式的卡号!
然后插入定单表!

以上3个操作我是放在了事务里面,随机密码是直接写在事务里面的,而卡号是生成密码以后
调用自己写的一个自定义函数生成!!

现出现了一个奇怪的定单,除了定单号和密码一样,其他完全相同!!
先不管它怎么提交的两次数据,关键问题是,为什么用事务处理了,也就是
每一张定单,应该是定单号,卡号,密码都应该不同,现在却是
定单号,密码不同,而卡号却相同

定单号和密码的生成代码,就不用说了,是很简单的,以下是生成前面2者以后,调用自定义函数的代码,卡号的格式是S1100001,S1100002,...... 增加的!

自定义函数:
CREATE function dbo.F_CSCS_GetAccount(@cardid varchar(20))
returns varchar(20)
as
begin
declare @maxID int,@newID varchar(20),@strLen int,@ssLen int,@listLen int
set @ssLen=8
if not exists(select 1 from userfillcard where cardaccount='S1100001' and cardid=@cardid)
  set @newID='S1100001' 
else
begin
      select @maxID=max(cast(right(cardaccount,len(cardaccount)-3) as int)) from userfillcard where iswhat=3 and cardid=@cardid and left(cardaccount,1)='S'
      set @maxID=@maxID+1
      set @newID='S11'+cast(@maxID as varchar(20))
      set @strLen=len(@newID)    
      set @listLen=@ssLen-@strLen
      while @listLen>0
      begin
                 set @newID=stuff(@newID,4,0,'0')
                 set @listLen=@listLen-1
      end
end
return (@newID)
end
----------------------
BEGIN TRAN
....        .                    --定单号
....                             --密码
set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) --调用
COMMIT TRAN

请教,怎么解释,到底什么原因,我是没办法了!!

8 个解决方案

#1


你的代码我没有仔细看(我最烦的就是看别人的代码了)

可能的原因:
1。你的设计中(表中)缺乏那种安全的校验,对于结果来说已经不重要了
2。就你的过程来说,有可能是两个人在不同的地方同时获取,但先后提交(insert)

#2


我的感觉就是,事务里调用自定义函数,给我的感觉就象脱离了事务一样
是不是这样呢?
至于没有对卡号检测,我承认也许有疏忽!
因为在获取卡号的时候,我是取得最大值,而不同于那种用户注册检测帐号,所以我没有判断

如果说非要检测才能解决,我会这样做的,关键我现在是要弄清楚,这个现象的实质原因!

#3


从表userfillcard取最大的数字生成卡号时.

则需要往userfillcard插入数据后,才能重新生成另外的卡号.否则每次都一样.

#4


楼上,不太懂你的意思,今天出现的这个问题,是个偶然问题!!一年了,才出现这么一张定单!

#5


不妨作个假设:

假定有两个如下事务一前一后执行:
----------------------------------------------------------
BEGIN TRAN
....                              --定单号
....                              --密码
set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) --调用
COMMIT TRAN
----------------------------------------------------------

先执行的事务为A,后执行的事务为B

在事务A执行完 set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) 语句之后,并且执行COMMIT TRAN之前

事务B也执行到了 set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) 语句

#6


还有,我想到是数据库并发性问题!以前因为没遇到,我就没深研过!
现在看来是遇到了,我觉得应该利用事务的存储过程,应该内部会自动处理并发性吧?!
还是说,我们要程序去实现!

#7


TO:libin_ftsafe(子陌红尘) 
我后来就是想了这个假设,和你的意思一样,那怎么解决这个问题,不是必然
但有可能发生!但是几率又不大,至少对我们来说!

#8


那我认为,如果在插入数据之前,检测如果存在相同,就回滚,是不是就解决了?!
如果是这样,看来,我还有待完善啊!

#1


你的代码我没有仔细看(我最烦的就是看别人的代码了)

可能的原因:
1。你的设计中(表中)缺乏那种安全的校验,对于结果来说已经不重要了
2。就你的过程来说,有可能是两个人在不同的地方同时获取,但先后提交(insert)

#2


我的感觉就是,事务里调用自定义函数,给我的感觉就象脱离了事务一样
是不是这样呢?
至于没有对卡号检测,我承认也许有疏忽!
因为在获取卡号的时候,我是取得最大值,而不同于那种用户注册检测帐号,所以我没有判断

如果说非要检测才能解决,我会这样做的,关键我现在是要弄清楚,这个现象的实质原因!

#3


从表userfillcard取最大的数字生成卡号时.

则需要往userfillcard插入数据后,才能重新生成另外的卡号.否则每次都一样.

#4


楼上,不太懂你的意思,今天出现的这个问题,是个偶然问题!!一年了,才出现这么一张定单!

#5


不妨作个假设:

假定有两个如下事务一前一后执行:
----------------------------------------------------------
BEGIN TRAN
....                              --定单号
....                              --密码
set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) --调用
COMMIT TRAN
----------------------------------------------------------

先执行的事务为A,后执行的事务为B

在事务A执行完 set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) 语句之后,并且执行COMMIT TRAN之前

事务B也执行到了 set @cardaccount=dbo.F_CSCS_GetAccount(@cardid) 语句

#6


还有,我想到是数据库并发性问题!以前因为没遇到,我就没深研过!
现在看来是遇到了,我觉得应该利用事务的存储过程,应该内部会自动处理并发性吧?!
还是说,我们要程序去实现!

#7


TO:libin_ftsafe(子陌红尘) 
我后来就是想了这个假设,和你的意思一样,那怎么解决这个问题,不是必然
但有可能发生!但是几率又不大,至少对我们来说!

#8


那我认为,如果在插入数据之前,检测如果存在相同,就回滚,是不是就解决了?!
如果是这样,看来,我还有待完善啊!