sqlserver2000,我在存储过程增加了事务处理,比如下面语句ALTER PROCEDURE p_bs_product_save
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
declare @iError int
BEGIN TRANSACTION aaa
update t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idset @iError = @@error /*保存错误号*/if @iError=0
commite tran aaa
else
rollback tran aaa
GO
我现在发现一个问题,在多用户同时并发时,好象出现死锁,比如在查询分析器里输入“select * from t_wh_billofdocument”,执行时,发现不动了好象出现死锁的状态,如果把“sql server 服务器管理器”停止后,再重新启动时,就没事了,如果出现多用户并发而导致死锁打不开某个表时,该如何处理呢?
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
declare @iError int
BEGIN TRANSACTION aaa
update t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idset @iError = @@error /*保存错误号*/if @iError=0
commite tran aaa
else
rollback tran aaa
GO
我现在发现一个问题,在多用户同时并发时,好象出现死锁,比如在查询分析器里输入“select * from t_wh_billofdocument”,执行时,发现不动了好象出现死锁的状态,如果把“sql server 服务器管理器”停止后,再重新启动时,就没事了,如果出现多用户并发而导致死锁打不开某个表时,该如何处理呢?
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
declare @iError intSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDBEGIN TRANSACTION aaa
update t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idset @iError = @@error /*保存错误号*/if @iError=0
commite tran aaa
else
rollback tran aaa
GO
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
declare @iError int--设置参数,如果一个事务中的任一一条SQL出错,整个事务都自动回滚
set xact_abort onBEGIN TRANSACTION aaaupdate t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idcommite tran aaa
GO
--2、如楼上所述,设置关键字--3、如果出现死锁,可以用kill清除掉这个进程,但应该从根本上避免死锁,应该从代码或实现方式上解决问题--4、如果已经死锁,还要查询数据,用with (nolock)如:select * from 表名 with (nolock)
如果出现死锁,要避免它,应该从代码或实现方式上解决问题,是不是说把我写的代码改
成你写的代码,会不会避免?比如你建议这样写:
ALTER PROCEDURE p_bs_product_save
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
declare @iError int--设置参数,如果一个事务中的任一一条SQL出错,整个事务都自动回滚
set xact_abort onBEGIN TRANSACTION aaaupdate t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idcommite tran aaa
GO
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
假如我这样写
declare @iError int--设置参数,如果一个事务中的任一一条SQL出错,整个事务都自动回滚
set xact_abort onBEGIN TRANSACTION aaaupdate t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idcommite tran aaa
GO如果有出错,就会整个事务都自动回滚,我想在代码里加一个回滚的提示,比如“当前数据保存不成功”,在这个代码里如何加?
有主键的话代码上看不出问题,
但如果处在关联更新的时候(A\B 表)看看是否有先更新次序不同的事务,这样的事务在并发时很容易造成死锁
还是查找下为什么锁吧.
管理->当前活动->用户 看看锁和和阻塞对象都在运行什么sql语句.看看是否逻辑顺序混乱造成的.
在代码里加一个回滚的提示,比如“当前数据保存不成功”,能不能直接在存储过程里写?如果行的话,如何写
--1、首先,对于严重的错误,用@@error是捕获不到的,系统会自动终止执行,应该按类似如下格式:ALTER PROCEDURE p_bs_product_save
@id int,
@code varchar (300) ,
@billcode varchar (300)
as
declare @iError int--设置参数,如果一个事务中的任一一条SQL出错,整个事务都自动回滚
set xact_abort onBEGIN TRANSACTION aaaupdate t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idcommite tran aaa
GO
我的问题:
(1)、如果有错误时就回滚时不用加上rollback tran aaa,难道只加上set xact_abort on就可以了
---------------------------------LZ的存储过程其实很简单,这样的存储过程如果多用户并发就会出现死锁根本就没道理,
如果SqlServer是这样的产品也不会有几个人用了
是否真的死锁运行sp_lock就知道所以LZ的问题应该是在updata语句上面,是不是更新要花很长时间?
我敢说LZ拿掉 BEGIN TRANSACTION 也会出现同样的问题,因为updata语句本身就有锁最后还是建议用 sp_lock 观察一下
BEGIN TRANSACTION aaaupdate t_wh_billofdocument set code=@code ,billcode=@billcode where id=@idcommite tran aaa
这样的代码,我觉得是没有必要用事务.浪费两行代码
(1)、如果有错误时就回滚时不用加上rollback tran aaa,难道只加上set xact_abort on就可以了---------------------------------------------
设置了set xact_abort on,不用加rollback tran aa,如果出错,就会自动回滚。当然,如果你想在每执行一句SQL后,用@@error判断一下,给出自己的错误提示信息,这样没有问题。但是一旦出现很严重的错促,这时判断@@error的代码根本不会执行,系统自动终止执行,自动回滚事务
A transaction is a logical unit of work made up of a series of statements (selects,
inserts, updates, or deletes).
那么提供的过程中只有且仅有一个UPDATE语句,这个语句它就是一个unit。如果确实是这样的话
(只有一个UPDATE语句)那么过程中定义的事务(aaa)就显得多余了,不需要用显式的事务来控制
它,sql server 自己会处理的。
2.楼主,对一些基本的概念还不十分清楚,所以再描述问题的时候都是不确定的口吻。
可以了解一下基本的概念如:什么阻塞?什么是死锁,有那些类型?两者有何不同,什么情况
下前者后发展成后者?如何监测识别阻塞和死锁?等等。把概念弄清楚了,再来分析你所遇到的
问题,自己就应该能搞定了。Good luck!
比如给你的T_WH_BILLOFDOCUMENT 增加一个列ROWCONTROL类型为ROWVERSION.
select @rowversion=rowversion from t_wh_billofdocument where id=@id
update t_wh_billofdocument set code=@code ,billcode=@billcode where id=@id and rowcontrol=@rowversion
以后在SELECT查询中都加上ROWCONTROL=@ROWCONTROL的条件
这样估计可以避免互相篡改的问题,你可以试下