日期:2014-05-17  浏览次数:20562 次

请教大侠,我这样写会不会死锁
set xact_abort ON
BEGIN TRAN
UPDATE Recharge SET status=1 WHERE id=@id
DECLARE @pay INT
select @pay=pay from Recharge where id=@id
......
COMMIT TRAN


update要加排他锁,就把条记录锁住了,select这条记录又要加共享锁,但是排他锁只有在事务结束时才释放,所以会永远停在select那里了,不知道我的想法对不对,请大侠指点一二,我这样写会不会死锁,应该怎么写.

------解决方案--------------------
不会,SQL是严格流程化的,在select 时候,肯定update是执行完毕的.
------解决方案--------------------
这要看你的事务隔离级别。
------解决方案--------------------
set xact_abort ON    
BEGIN TRAN         
UPDATE HumanResources.Department SET NAME='test123' WHERE DepartmentID=10
DECLARE @pay INT        
select @pay=DepartmentID from HumanResources.Department where DepartmentID=10        
COMMIT TRAN
 
在2008的示例数据库下测了一下,不会死锁
------解决方案--------------------
引用:
引用:
SQL code?123456set xact_abort ON    BEGIN TRAN         UPDATE HumanResources.Department SET NAME='test123' WHERE DepartmentID=10DECLARE @pay INT        select @pay=DepartmentI……

不奇怪,这面有2个关键点,
1,首要要搞清阻塞跟死锁的区别,它们两个是完全不同的概念,另外根据你的描述,你想表达的应该是问是不是发生阻塞,阻塞是可能发生的,但是死锁应该不会。

2,事务的隔离级别是针对session级别的,也就是说同一个session内,是不会发生阻塞的,你上面的那个transaction在同一个session,所以update跟Select之间不会相互阻塞,当然,如果你在2个session里同时运行上面的事务,那是可能会发生阻塞的,并且由于你访问资源的顺序是一致的,所以应该不会死锁。

明白了吗?
------解决方案--------------------
引用:
引用:
引用:引用:
SQL code?123456set xact_abort ON    BEGIN TRAN         UPDATE HumanResources.Department SET NAME='test123' WHERE DepartmentID=……

没错,就是这样。
这个你都认识啊,呵呵。不过我那个沙迦,