设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3 1)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran 若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒
以上为转载资料
想问:同时启动了update和select,则update请求更新锁,select请求共享锁,那么这两个所是不兼容的,为什么知道是update先请求到了更新锁,然后等其完成当前事务后,释放由更新锁转化的排他锁,然后等待30秒,才允许select请求共享锁呢,
为什么不是第二个事物先请求到共享锁,完成其当前事务,然后才允许第一个事务请求更新锁呢? 另外,更新锁执行一个带where的update语句时,是不是先转化为共享锁,查询到记录,然后在转为排它锁,进行更新呢?
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3 1)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A='aa'
where B='b2'
waitfor delay '00:00:30' --等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B='b2'
commit tran 若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒
以上为转载资料
想问:同时启动了update和select,则update请求更新锁,select请求共享锁,那么这两个所是不兼容的,为什么知道是update先请求到了更新锁,然后等其完成当前事务后,释放由更新锁转化的排他锁,然后等待30秒,才允许select请求共享锁呢,
为什么不是第二个事物先请求到共享锁,完成其当前事务,然后才允许第一个事务请求更新锁呢? 另外,更新锁执行一个带where的update语句时,是不是先转化为共享锁,查询到记录,然后在转为排它锁,进行更新呢?
共享 (S) 锁允许并发事务读取 (SELECT) 一个资源。资源上存在共享 (S) 锁时,任何其它事务都不能修改数据。一旦已经读取数据,便立即释放资源上的共享 (S) 锁,除非将事务隔离级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享 (S) 锁。 更新锁
更新 (U) 锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读取记录,获取资源(页或行)的共享 (S) 锁,然后修改行,此操作要求锁转换为排它 (X) 锁。如果两个事务获得了资源上的共享模式锁,然后试图同时更新数据,则一个事务尝试将锁转换为排它 (X) 锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它 (X) 锁以进行更新。由于两个事务都要转换为排它 (X) 锁,并且每个事务都等待另一个事务释放共享模式锁,因此发生死锁。 若要避免这种潜在的死锁问题,请使用更新 (U) 锁。一次只有一个事务可以获得资源的更新 (U) 锁。如果事务修改资源,则更新 (U) 锁转换为排它 (X) 锁。否则,锁转换为共享锁。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fredrickhu/archive/2009/09/21/4574867.aspx
从CPU的处理机制上来说,是不存在绝对并发的吧?就算是多线程也得一个一个线程启动吧?
即使这两个会话同时提交批处理,这两个批处理同时到达 SQL Server 实例,实例只会将这两个批处理放入“执行队列”中,然后调度工作线程来处理这两个批处理,这样必然会有先后次序。update 语句在修改记录前需要定位记录,在定位过程中会请求记录的 u 锁,在更新记录时将 u 锁转换为 x 锁。