有关事务处理的多用户并发出现死锁的问题
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=@id   
 set   @iError   =   @@error   /*保存错误号*/   
 if   @iError=0 
 commite   tran   aaa 
 else 
 rollback   tran   aaa 
 GO     
 我现在发现一个问题,在多用户同时并发时,好象出现死锁,比如在查询分析器里输入“select   *   from   t_wh_billofdocument”,执行时,发现不动了好象出现死锁的状态,如果把“sql   server   服务器管理器”停止后,再重新启动时,就没事了,如果出现多用户并发而导致死锁打不开某个表时,该如何处理呢?
------解决方案----------------------1、首先,对于严重的错误,用@@error是捕获不到的,系统会自动终止执行,应该按类似如下格式:   
 ALTER PROCEDURE p_bs_product_save 
 @id int, 
 @code varchar (300) , 
 @billcode varchar (300) 
 as 
 declare @iError int   
 --设置参数,如果一个事务中的任一一条SQL出错,整个事务都自动回滚 
 set xact_abort on   
 BEGIN TRANSACTION aaa   
 update t_wh_billofdocument set code=@code ,billcode=@billcode where id=@id   
 commite tran aaa 
 GO     
 --2、如楼上所述,设置关键字   
 --3、如果出现死锁,可以用kill清除掉这个进程,但应该从根本上避免死锁,应该从代码或实现方式上解决问题   
 --4、如果已经死锁,还要查询数据,用with (nolock)   
 如:   
 select * from 表名 with (nolock)   
------解决方案--------------------set xact_abort on 在事务处理时是必要的, 
 有主键的话代码上看不出问题, 
 但如果处在关联更新的时候(A\B 表)看看是否有先更新次序不同的事务,这样的事务在并发时很容易造成死锁
------解决方案--------------------并发更新一个表的话如果并发多始终可能死锁,因为更新含有隐式游标,即使有索引也有冲突的可能,更改事务隔离级别会带来脏读等问题,,当发生死锁时回滚是没有用的,因为进程已经阻塞,所以最好的办法是不用事务或者从代码上避免死锁,可以参考哲学家用餐模型的算法 
------解决方案--------------------在多用户同时并发时,好象出现死锁 
 ---------------------------------   
 LZ的存储过程其实很简单,这样的存储过程如果多用户并发就会出现死锁根本就没道理, 
 如果SqlServer是这样的产品也不会有几个人用了 
 是否真的死锁运行sp_lock就知道   
 所以LZ的问题应该是在updata语句上面,是不是更新要花很长时间? 
 我敢说LZ拿掉 BEGIN TRANSACTION 也会出现同样的问题,因为updata语句本身就有锁   
 最后还是建议用 sp_lock 观察一下   
------解决方案--------------------1.我们先看事务的简要的定义: 
 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!   
------解决方案--------------------hb_gx(高升) ( ) 信誉:100 说的很对我觉得   
 要么你不用事务,关于互相篡改数据的问题,可以增加一个ROWVERSION列来控制 
 比如给你的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的条件 
 这样估计可以避免互相篡改的问题,你可以试下