sql2000表死锁
一业务系统,在进行业务处理的时候,都调用以下存储过程,来取得单据序号(recnum),同时进行业务处理时出现表死锁。有什么方法解决?
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO
ALTER PROCEDURE SOF_getmaxbh
@biaoshi varchar(3), --单据类型标识
@addflag integer, --0,1 在前台使用;2 组成一个号返回,序号不加1(结转号),3 序号加 1 返回(单据编号);
@maxbh varchar(11)=NULL output --直接返回编号
AS
/***************************************************************/
--过程主题:获得单据编号 errorID=1800
/***************************************************************/
--内部变量声明
declare @recnum integer,
@rowcount integer
set @recnum=0
/*非事务内容执行*/
--每一过程拥有一唯一区界号,过程内的异常编号在此基础上增加
declare @errcode integer
set @errcode=1800
declare @return integer
set @return=0
--启动事务处理
declare @tran_point int --控制事务嵌套
set @tran_point=@@trancount --保存事务点
if @tran_point=0
begin tran tran_SOF_getmaxbh
else
save tran tran_SOF_getmaxbh
if @addflag=1 or @addflag=3
begin
update maxbh set @recnum=recnum=recnum+1 where biaoshi=@biaoshi
set @rowcount=@@rowcount
if @@error<>0
begin
set @return=1
goto err_lab
end
end
else
begin
select @recnum=recnum from maxbh(nolock) where biaoshi=@biaoshi
end
if @rowcount=0
begin
set @recnum=0
insert into maxbh (biaoshi,maxbh,mkbh,recnum) values (@biaoshi,'','',@recnum)
end
--返回结果
declare @s_recnum varchar(11)
set @s_recnum=LTRIM(str(@recnum))
if @addflag>1
set @maxbh=@biaoshi+ REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum
else
select @biaoshi+ REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum as recnum
--结束事务处理
if @tran_point=0
commit tran tran_SOF_getmaxbh
goto return_lab
err_lab:
if @return<100 set @return=@errcode +@return
rollback tran tran_SOF_getmaxbh
return_lab:
return @return
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
问题点数:100、回复次数:7Top
1 楼gc_ding(施主,给个妞泡好么)回复于 2006-12-04 18:44:10 得分 0
帮项Top
2 楼zjcxc(邹建)回复于 2006-12-04 18:47:26 得分 100
-- 应该让事务尽可能小, 包含最小的处理语句
-- 楼主这个可以改成这样的
ALTER PROCEDURE SOF_getmaxbh
@biaoshi varchar(3), --单据类型标识
@addflag integer, --0,1 在前台使用;2 组成一个号返回,序号不加1(结转号),3 序号加 1 返回(单据编号);
@maxbh varchar(11)=NULL output --直接返回编号
AS
/***************************************************************/
--过程主题:获得单据编号 errorID=1800
/***************************************************************/
--内部变量声明
declare @recnum integer,
@rowcount integer
set @recnum=0
/*非事务内容执行*/
--每一过程拥有一唯一区界号,过程内的异常编号在此基础上增加
declare @errcode integer
set @errcode=1800
declare @return integer
set @return=0
IF @addflag=1 or @addflag=3
BEGIN
--启动事务处理
declare @tran_point int --控制事务嵌套
set @tran_point=@@trancount --保存事务点
if @tran_point=0
begin tran tran_SOF_getmaxbh
else
save tran tran_SOF_getmaxbh
DECLARE @err int
update maxbh set @recnum=recnum=recnum+1 where biaoshi=@biaoshi
SELECT @rowcount=@@rowcount, @err = @@ERROR
if @err<>0
begin
set @return=1
goto err_lab
end
if @rowcount=0
begin
set @recnum=0
insert into maxbh (biaoshi,maxbh,mkbh,recnum) values (@biaoshi,'','',@recnum)
end
if @@ERROR<>0
begin
set @return=1
goto err_lab
end
--结束事务处理
if @tran_point=0
commit tran tran_SOF_getmaxbh
END
ELSE
begin
select @recnum=recnum from maxbh(nolock) where biaoshi=@biaoshi
end
--返回结果
declare @s_recnum varchar(11)
set @s_recnum=LTRIM(str(@recnum))
if @addflag>1
set @maxbh=@biaoshi+ REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum
else
select @biaoshi+ REPLICATE('0',11-len(@biaoshi)-len(@s_recnum))+@s_recnum as recnum
--结束
goto return_lab
err_lab:
if @return<100 set @return=@errcode +@return
rollback tran tran_SOF_getmaxbh
return_lab:
return @return
GOTop
3 楼zjcxc(邹建)回复于 2006-12-04 18:48:41 得分 0
试试上面调整之后和算法
另外, 楼主的处理语句中, 下面是有问题的
update maxbh set @recnum=recnum=recnum+1 where biaoshi=@biaoshi
set @rowcount=@@rowcount
if @@error<>0 -- 这里得到的是上面那个SET赋值是否有错误, 如果UPDATE出错, 则不会被捕获到
begin
set @return=1
goto err_lab
endTop
4 楼zjcxc(邹建)回复于 2006-12-04 18:49:48 得分 0
需要说明的是, 楼主的事务有可能是依赖于外部事务的, 这样分析起来就比较复杂了, 因为死锁不一定跟你帖出的这个过程有关, 有可能是外部的处理语句导致.Top
5 楼eason2000(eason)回复于 2006-12-05 09:02:29 得分 0
老大说的没错,我这个过程在很多业务里都要调用,来取得当前的单据序号。下面是我一调用的该过程的语句,您帮我看看?
Top
6 楼eason2000(eason)回复于 2006-12-05 09:06:46 得分 0
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO
-- 进销单据存储
ALTER procedure SBP_jx_dj
@gzid char(20),
@djlxbs char(3)
as
/***************************************************************
过程主题:进销单据存储 errorID=900
2002-11-21 zxm 出库且结算登记 cwk 时单据号记录错误。
2002-12-04 zxm 机器号辅助录入应根据高级选项进行存盘。
2003-01-06 liush 增加换货管理,换货标志登记在cwk中。
2004-12-15 lixd 增加else语句,连接多个IF语句
2005-04-28 Victor Ben 登记ywjsmx前,计算yisfje错误,退回单增加(@isth<>-1)判断
***************************************************************/
--每一过程拥有一唯一区界号,过程内的异常编号在此基础上增加
declare @errcode integer
set @errcode=900 /* 进销单据存储*/
declare @return integer /*返回结果的初始化*/
set @return=0
declare
@djbh char(14),
@jsdjlx char(3),
@jsdjbh char(14),
@jxlx char(1),
@djlx char(3),
@rq char(10),
@dwbh char(11),
@bm char(20),
@ywy char(20),
@username char(20),
@jzhh char(11),
@zhy char(30),
@isjs char(2),
@jsfsid char(11),
@jiesje dec(14,2),
@zhph char(12),
@cor_ysh dec(20,2),
@cor_yf dec(20,2),
@tmp_zoo dec(14,2),
@lastsj char(2), --最后售价管理
@mu_dingd char(2), --允许订单多次执行
@chonghong char(2), --冲红
@ck_auto_ph char(2), --出库自动分摊批号
@autoph int, --自动分摊批号
@djmxfzjqh char(2), --机器号辅助录入
@m int,
@isth int, --退货
@istbj int, --退补价
@is_hh char(2),
@bendian char(3)
set @zhph=''
set @djbh=''
set @bm=''
set @ywy=''
set @zhy=''
set @rq=''
set @isjs='否'
set @jsfsid=''
set @jiesje=0
set @cor_ysh=0
set @cor_yf=0
set @tmp_zoo=0
set @m=0
set @isth=1
set @istbj=1
set @lastsj='否'
set @chonghong='否'
set @mu_dingd='否'
set @ck_auto_ph='否'
set @autoph=0
set @djmxfzjqh='否' --机器号辅助录入
set @is_hh='否'
set @bendian=''
--增加一临时缓存
select @djbh=case fieldname when 'djbh' then left(fieldvalue,14) else @djbh end,
@dwbh=case fieldname when 'dwbh' then left(fieldvalue,11) else @dwbh end,
@bm=case fieldname when 'bm'then left(fieldvalue,20) else @bm end,
@ywy=case fieldname when 'ywy'then left(fieldvalue,20) else @ywy end,
@username=case fieldname when 'username'then left(fieldvalue,20) else @username end,
@zhy=case fieldname when 'zhy'then left(fieldvalue,30) else @zhy end,
@rq=case fieldname when 'rq' then left(fieldvalue,10) else @rq end,
@isjs=case fieldname when 'isjs'then left(fieldvalue,2) else @isjs end,
@jsfsid=case fieldname when 'jsfsid'then left(fieldvalue,11) else @jsfsid end,
@zhph=case fieldname when 'zhph'then left(fieldvalue,12) else @zhph end,
@mu_dingd=case fieldname when 'MU_DINGD'then left(fieldvalue,2) else @mu_dingd end,
@chonghong=case fieldname when 'dj_chonghong'then left(fieldvalue,2) else @chonghong end,
@ck_auto_ph=case fieldname when 'ck_auto_ph'then left(fieldvalue,2) else @ck_auto_ph end,
@djmxfzjqh=case fieldname when 'DJMXFZ'then left(fieldvalue,2) else @djmxfzjqh end,
@lastsj=case fieldname when 'ZHSHJ'then left(fieldvalue,2) else @lastsj end,
@bendian=case fieldname when 'bendian' then left(fieldvalue,3) else @bendian end,
@jiesje=case fieldname when 'sjsz' then round(convert(decimal(14,2),rtrim(fieldvalue)),2) else @jiesje end,
@is_hh=case fieldname when 'is_hh' then left(fieldvalue,2) else @is_hh end
from tmp_dj_mast (nolock)
where gzid=@gzid and fieldname in ('djbh','dwbh','bm','ywy','username','zhy','rq','isjs','jsfsid','zhph','sjsz','ZHSHJ','MU_DINGD','dj_chonghong','ck_auto_ph','DJMXFZ','is_hh','bendian')
set @jxlx=left(@djbh,1)
set @djlx=left(@djbh,3)
--select @istbj=case @djlx when 'JHB' then 0 when 'XSB' then 0 end,@isth=case @djlx when 'JHC' then -1 when 'XSC' then -1 end,@isjs=case @isjs when '' then '否' end
if @djlx='JHB' or @djlx='XSB'
begin
set @istbj=0
end
if @djlx='JHC' or @djlx='XSC'
begin
set @isth=-1
end
if @isjs=''
begin
set @isjs='否'
end
if @djlx='XSA'
begin
if @ck_auto_ph='是'
set @autoph=1
end
exec @return=SOF_getmaxbh 'JZH',2,@jzhh OUTPUT
if @return>0
goto err_lab
--启动事务处理
declare @tran_point int --控制事务嵌套
set @tran_point=@@trancount --保存事务点
if @tran_point=0
begin tran tran_jxdj
else
save tran tran_jxdj
--创建临时结构
create table #t_djmx (
djbh char(14) null default '',
rq char(10) null default '',
dwbh char(11) null default '',
bm char(20) null default '',
ywy char(20) null default '',
username char(20) null default '',
zhy char(30) null default '',
spid char(11) null default '',
xgdjbh char(14) null default '',
isjs char(2) null default '否',
hw char(11) null default '',
pihao char(20) null default '',
pici char(20) null default '',
baozhiqi char(10) null default '',
miejph char(12) null default '',
sxrq char(10) null default '',
dj_sn integer null default 0,
dj_sort integer null default 0,
recnum integer null default 0,
shl decimal(14,2) null default 0,
dj decimal(16,6) null default 0,
je decimal(14,2) null default 0,
shlv decimal(14,2) null default 0,
hshj decimal(16,6) null default 0,
hsje decimal(14,2) null default 0,
she decimal(14,2) null default 0,
lshje decimal(14,2) null default 0,
ml decimal(14,2) null default 0,
plcj decimal(14,2) null default 0,
lshj decimal(14,2) null default 0,
buckcb decimal(14,2) null default 0,
bukccb decimal(14,2) null default 0,
canssl decimal(14,2) null default 0,
quxsl decimal(14,2) null default 0,
duiydjbh char(14) null default '',
duiydj_cn int null default 0
)Top
7 楼caixia615(*^_^*)‵My ɡīr!.ˊ想念妳ˋ 。(*^_^*)回复于 2006-12-05 09:15:02 得分 0
mark,学习Top




