lakers009 发表于 2016-10-30 06:25:29

SQL Server 的锁机制

   SQL Server支持多用户共享同一数据库,但是,当多个用户对同一个数据库进行修改时,会产生并发问题,是用锁可以解决用户存取数据的这个问题,从而保证数据库的完整性和一致性。对于一般的用户,通过系统的自动锁管理机制基本可以满足是用要求,但如果对数据库安全、数据库完整性和一致性有特殊要求,则需要亲自控制数据库的锁和解锁,这就需要了解SQL Server 的锁机制,掌握锁的只用方法。
  
  锁的内涵与作用:
   数据库中数据的并发操作经常发生,而对数据的并发操作会带来下面的一些问题:脏读、幻读、非重复性读取、丢失更新。
  脏读:
  脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
  幻读:
  
事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样.一般解决幻读的方法是增加范围锁RangeS,锁定检锁范围为只读,这样就避免了幻读。
  
  非重复性读取:
  如果一个事物不止一次的读取相同的记录,但在两次读取中间有另一个事务刚好修改了数据,则两次读取的数据将出现差异,此时就发生了非重复性读取。例如事务1和事务2都读取一条工资为2310的数据行,如果事务1将记录中的工资修改为2500并提交,
  则事务2中使用的员工工资任为2310.

  丢失更新:

  一个事务更新了数据库之后,另一个事务再次对数据库更新,此时系统只能保留最后一个数据的修改。
   使用锁将可以实现并发控制,并能保证多个用户同时操作同一数据库中的数据而不发生上述数据不一致的问题。

  

  可锁定资源与所得类型:
  可锁定资源:

  使用SQL Server 中的锁机制可以锁定不同的类型的资源,即具多粒度锁,为了使锁的成本降到最低,SQL Server 会自动将资源锁定在合适的层次,锁定层次越高,它的粒度就越粗。锁定在较高的层次,例如表,就限定了其他市区对表中任意部分进行访问,但需要的资源较少,应为要维护的锁较少;在说较小的层次,例如行,可以增加并发但需要较大的资源,应为锁定了许多行,需要控制许多锁。对于SQL Server 来说,可以根据粒度大小分为6种可锁定的资源,这些资源由粗到细分别是:
  数据库>>表>>区段页>>页>>键>>行

  锁的类型:

   SQL Server 中提供了多种锁模式,在这些类型的锁中,有些类型之间可以兼容,有些类型之间的锁是不可以兼容的。锁模式决定了并发事务访问资源的方式。江面介绍几种常用的锁:
  更新锁:
  一般用于可更新的资源,可以防止多个会话在读取、锁定,以及可能进行的资源更新时出现死锁的情况,当一个事务查询数据以便进行修改时,可以对数据项施加更新锁,如果事务修改资源,则资源自动转换成排它锁,否则转换成共享锁。一次只有一个事务可以获得资源的更新锁,它允许其他事务对资源的共享访问,但阻止排他式的访问。
  排他锁:
   用于修改数据操作,确保不会同时对同一资源进行多重更新。
  共享锁:
  用于读取数据操作,允许多个事务读取相同的数据,但不允许其他事务修改当前的数据,当多个事务读取一个资源时,资源上存在共享锁,任何其他事务都不能修改事务,除非将事务隔离级别设置为可重复读取或更高级别,或者在事务生存周期内用锁定提示对共享锁进行保留,那么数据一旦完成读取,资源上的共享锁立即得以释放。
  键范围锁:
  可防止幻读,通过保护行之间键的范围,还可以防止对事务访问的记录经进行幻象插入或删除。
  架构锁:
   执行表的数据定义操作时使用架构修改锁,在架构修改锁其作用的期间,会防止对表的并发访问。这意味着在释放架构修改锁之前,该锁之外的所有操作都将被阻止。
页: [1]
查看完整版本: SQL Server 的锁机制