zoukankan      html  css  js  c++  java
  • 关系型数据库的完整性---锁、 约束 、键、 索引

    RDBMS能在事务中维护数据的完整性,这是通过数据库对象实现的多种机制来实现的,下面列出的是4个最重要的对象:

    • 约束
    • 索引

          在SQL Server中,锁可以使多个用户同时访问,同一数据,并且保证在读取数据时,数据不会被修改。同时,锁也用来确保一个进程在修改数据时,不和其他进行数据修改操作或者数据读取操作的进程发生冲突。

          SQL Server以连接为单位对锁进行管理,这就是说,一个锁不能被多个连接同时持有;SQL Server也以事务为单位对锁进行管理,和多个连接不能同时持有同一个锁一样,多个事务也不能同时持有,同一个锁。

           比如,假如一个应用程序打开了一个SQL Server连接,这个连接在某个表上,被赋予了共享锁,这个应用程序就不能再打开一个可以修改该表数据的新连接。对事物也是一样。如果一个应用程序启动了一个用于修改特定数据的事务,那么在这个事务的工作完成之前,其他任何事物,都不能修改这些数据。即使多个事务共享相同的连接,上述情况也成立。

          SQL Server使用6种类型的锁,更准确的说,是6种资源锁模式:

    • 共享
    • 更新
    • 排他
    • 意向
    • 模式
    • 批量更新

    共享锁,更新锁,排他锁和意向锁可用于表或索引的行、页(表,或者索引所用的8KB的存储页面)、扩展(64KB的8个连续的索引或者表页面)、表,数据库。

    模式锁与批量更新锁适用于表。

           共享锁

           共享锁允许多个连接和事务同时读取所分配的共同资源。只要给连接和事务授予了共享锁,任何其他连接或事务就不能修改数据。当一个应用程序成功的读取了数据之后,共享锁通常会被释放,但在某些特殊情况下,这个动作是可以修改的。例如:给整个事务分配了共享锁,保证事务基于的数据,在该事务完成之前不被修改,从而最大限度的确保数据的一致性。这个扩展锁,可用于事务一致性必须100%保证的情况,但持有锁的代价是降低了数据的并发访问,例如,要从储蓄账户中取100美元,在包含储蓄账户的余额上放置一个共享锁。这些数据用于确保有足够的资金支持这个取款操作。最好禁止其他连接修改该余额,直到取款操作完成为止。 由于共享锁之间是互相兼容的,因此,不同的事务和连接在读取相同的数据时,不会发生冲突。

          更新锁

          SQL Server使用更新锁,在防止出现死锁的情况。出现死锁是很糟糕的,通常死锁是由于拙劣的编程技术造成的。当两个进程争夺同一个资源时,就将发生死锁。回到前面银行的例子:在这个假定的银行事务中,我妻子和我同时上线,将储蓄账户中的资金转帐到支票账户上。碰巧我们同时要进行转账,于是两个进程分别启动并执行了转账操作。当我的进程访问这两个账户时,进程在资源上发出了共享锁。到目前为止一切还算正常,但是当我们的进程试图修改资源时,混淆便随之而来了。首先,我妻子的进程尝试将共享锁升格为排他锁,以便对数据进行修改。几乎同时,我的进程也尝试进行相同的升格操作。然而,我们所共有的共享锁阻止了任何一个进程,实现升格到排他锁的企图。由于没有一个进程愿意释放其,共享锁,就发生了死锁。

          SQL Server不会对死锁现象特别关照,假如死锁发生了,SQL Server就会自动选择其中的一个进程,将它作为牺牲品而停止。SQL Server选择与其关联代价最小的进程,停止它,回滚相关事务,然后向相关应用程序中返回错误代码1205.如果用户正确的捕捉到了错误,就会得到这样的消息:“事务##在X资源上与其他进程,出现了死锁,并被选择为死锁的牺牲品,重新运行事务”。

          为了防止死锁发生,SQL Server通常使用更新锁来代替共享锁。只有一个进程可以得到更新锁,这样可以防止与其相对的进程升格其拥有的锁,其底线是,如果以更新为唯一目的而进行了读操作,则SQL Server可以发出一个更新锁,而不是共享锁,以便避免潜在的死锁危险。SQL提供了防止死锁的逻辑,只要细心的规划与实现,就可以避免死锁的产生。

          排他锁

          在执行修改操作时,SQL Server通常发出排他锁。在更改一行汇总的某个字段值的时候,SQL Server授予相关进程访问此行的排他访问权限。这样的排他访问,可以防止任何并发事务或者连接的相关进程,对处于修改中的数据,进行读、更新、删除操作。排他锁与任何其他类型的锁都不兼容。

          意向锁

          为了防止任何一个并发事务,或者连接中的进程,在一个已经被其他进程锁住的资源上,放置排他锁,SQL Server设计了意向锁。比如,执行一个事务,在表中更新单个行,SQL Server在该行上授予此事务排他锁的同时,也在包含此行的表上授予此事务意向锁。这样就能防止其他进程在该表中放置排他锁。    

         举一个现实中的例子:它可以解释SQL 编程中意向锁的行为:用户住进了SQL旅馆的404房间,现在具有使用4楼的房间4的唯一(排他)权限。旅馆的其他主顾都不允许进入此房间。而且没有主顾可以将旅馆的所有房间都预定下来,因为404房间已经被用户单独占用。对于旅馆,用户就有了意向锁;而对于404房间,用户有排他锁。意向锁,与其他比它低级的锁,都是兼容的。

         批处理更新锁

         表上的批处理更新锁允许多个批处理加载线程,把数据加载到表中,同时禁止其他类型的数据访问。在表上启用表锁定时,或者用批处理操作选择表锁定选项时,就发出了批处理更新锁。 

         键范围锁

         在使用可串行化的隔离级别时,键范围锁保护结果集中隐含的一个行范围,不被T-SQL语句读取。可串行化的隔离级别要求,在事务中每次查询时,都必须获得相同的行集。键范围锁,禁止其他事务插入其键值(由可串行化的事务读取)在指定的范围内的新行,来满足这个要求。

        

     

  • 相关阅读:
    iSCSI又称为IPSAN
    文档类型定义DTD
    HDU 2971 Tower
    HDU 1588 Gauss Fibonacci
    URAL 1005 Stone Pile
    URAL 1003 Parity
    URAL 1002 Phone Numbers
    URAL 1007 Code Words
    HDU 3306 Another kind of Fibonacci
    FZU 1683 纪念SlingShot
  • 原文地址:https://www.cnblogs.com/caofangsheng/p/5273235.html
Copyright © 2011-2022 走看看