SqlServer 默认隔离级别是 read committed 提交读,select查询可能会有共享锁,即select操作发生时,update等排他操作进入等待,其他select操作可以进行,共享这把锁。
反之,如果update操作等排它锁还未释放时(即事务没有提交或者回滚),select操作进入等待,获取不了共享锁。
如果是Mysql,隔离级别是可重复读,即一个事务里要保证select出来的数据是一样的。所以隔离级别越高,就越耗资源。
读操作可以不需要S LOCK(共享锁)吗?
可以。
1. SELECT * FROM TableName WITH(NOLOCK)
或者:
2.SQL SEVER有个优化机制,在没有脏读可能的情况下,不需要去申请S LOCK
那么,select查询会锁表吗?
有可能,某个查询使用非聚集索引来select数据,那么它会在非聚集索引上持有一个S锁。当有一些select的列不在该索引上,它需要根据rowid找到对应的聚集索引的那行,然后找到其他数据。而此时,第二个的查询中,update正在聚集索引上忙乎:定位、加锁、修改等。但因为正在修改的某个列,是另外一个非聚集索引的某个列,所以此时,它需要同时更改那个非聚集索引的信息,这就需要在那个非聚集索引上,加第二个X锁。select开始等待update的X锁,update开始等待select的S锁,死锁发生了。