最近在解决一些死锁的问题,有一个疑问,更新锁和排他锁都是在数据更新时产生的,并且都与与S锁不兼容,既然有了排他锁,为何还需要更新锁,msdn上面讲的太笼统了,谁能帮忙解释下,谢谢!
------解决方案--------------------
排它锁:
当数据发生增删改操作并修改数据时,会自动在这些数据上加上排它锁。一个特定资源上只能有一个排它锁。当资源上加上排它锁,其他任何锁都不能加在相同的资源上,因为和其他任何类型的锁不兼容。排它锁直到事务结束后才释放。其他进程可以使用hints来读取有排它锁的数据。
更新锁:
更新锁并不是一个单独类型的锁,它是共享锁和排它锁的混合体。当数据需要修改前,SQLServer需要扫描表以便找出需要修改的资源,此时会加上更新锁。使用hints之后,进程可以要求使用更新锁,有时候更新锁还可以预防死锁的发生。更新锁允许其他进程读取数据,也能保证数据自上一次读取之后不会被修改。但是更新锁不会允许你修改数据,因为任何修改数据操作都需要加上排它锁。更新锁实际上是为排它锁做准备。一个资源上可以有很多资源加上的共享锁,但是只能有一个进程可以加上更新锁。也就是说当一个进程对一个资源加上更新锁之后,其他经常无法对这个资源申请更新锁或者排它锁。持有更新锁的进程可以把更新锁转换成排它锁,因为更新锁与其他进程的任何锁都不兼容。你可以认为更新锁是“意图去更新”的锁,更新锁不足以更新数据,因为还需要排它锁才可以直接修改数据。排他锁的顺序访问有助于避免死锁的发生。更新锁会持续到事务结束或者到转换成排它锁为止。
更新锁不仅仅用于UPDATE操作。SQLServer对所有数据修改都要使用更新锁来查找更新前的实际数据。这些操作包括更新、删除和在有聚集索引的表上insert时。SQLServer必须先使用聚集索引查找可以增加新行的数据的准确位置。当SQLServer仅仅在搜索的时候,会使用更新锁保护数据。在找到之后,会把更新锁转换成排它锁。