关系型数据库的完整性---锁、 约束 、键、 索引

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语句读取。可串行化的隔离级别要求,在事务中每次查询时,都必须获得相同的行集。键范围锁,禁止其他事务插入其键值(由可串行化的事务读取)在指定的范围内的新行,来满足这个要求。

时间: 2024-10-16 13:15:25

关系型数据库的完整性---锁、 约束 、键、 索引的相关文章

数据库的数据类型、约束、索引、视图

数据库的数据类型.约束.索引.视图 一.数据类型 (一)数值型数据 整数 int,bigint,smallint 小数 float,real,decimal(长度,精度),numeric(长度,精度) 常用的:float(相当于C#中的double),decimal (二)字符数据 char(n) 最大存储量:8000英文字符,4000汉字:数量一定的字符用char(n)如身份证.学号,用n限制字符数量输入: varchar(n) 最大存储量:8000英文字符,4000汉字: 数量变化的字符用v

sqlserver数据库设计完整性与约束

1 use StudentManageDB 2 go 3 --创建主键约束 4 5 if exists(select * from sysobjects where name='pk_StudentId') 6 alter table Students drop constraint pk_StudentId 7 alter table Students add constraint pk_StudentId primary key(StudentId) 8 9 --创建唯一约束 10 if e

redis(jedis)相关API ,实现与关系型数据库相似的功能

本文简单介绍了在使用jedis操作redis这个nosql数据库过程中,总结的一些问题,例如使用jedis实现形如关系型数据库的数据关联关系处理. 分三个层面: 1:单表数据处理,新增一行数据到数据库中,如果存在主键id是自增情况的条件下,如何新增数据集合到数据库行数据: 2:一对多关联关系,本文举例形如---学生&&成绩: 一个学生包含多个学科的成绩,某一个学科的的成绩属于某个学生: 3:多对多关联关系,本文举例例如---文章&&标签: 一篇文章可以添加多个标签,某一个标

Python3编写网络爬虫12-数据存储方式五-非关系型数据库存储

非关系型数据库存储 NoSQL 全称 Not Only SQL 意为非SQL 泛指非关系型数据库.基于键值对 不需要经过SQL层解析 数据之间没有耦合性 性能非常高. 非关系型数据库可细分如下: 键值存储数据库: 代表有Redis.Voldemort.和Oracle BDB等. 列存储数据库:代表有Cassandra.HBase.和Riak等. 文档型数据库:代表有CouchDB.Mongodb等. 图形数据库:代表有Neo4J.InfoGrid.Infinite.Graph等. 对于爬虫的数据

mysql基本认识【关系型数据库和nosql、mysql操作流程和体系,库操作,表操作,数据的操作,字符集的操作,以及php作为client操作数据库】对连接本身没有疑问

1.关系型数据库永久性保存数据的仓库php的变量只是php脚本执行期间,临时性保存变量的空间[使用内存空间临时保存] 关系型数据库:利用二者的关系来描述实体的信息.[利用二维表字段名和字段值来进行描述][关系型数据库根本不是可以使用外键将两个表构建成关联的意思,而是实现描述实体的二维表的形式] nosql:not only sql[sql表示操作关系型数据的语言]所以nosql指的就是非关系型数据库[典型的是键值对型的数据(redis.memcache)][nosql可以视情况添加信息,不需要对

主键约束,唯一性约束,唯一性索引

1)主键列:比如我们在表A中指定ID为主键,Oracle数据库会自动创建一个同名的唯一索引 可以通过 select constraint_name,constraint_type from user_indexes ui where ui.table_name='A'来查看主键上的唯一索引,如果此时我们在给ID列去创建唯一性索引或者非唯一性索引的话,都会报错,当然指定主键之后自动也会生成主键约束,主键就是一种约束 (2)非主键列:我们在非主键列上创建一个唯一性约束,Oracle同样自动创建了一个

数据库完整性及约束

转载请注明出自朱朱家园http://blog.csdn.net/zhgl7688 1.  数据完整性:常用三种类型的约束保证数据完整性有域(列)完整性.实体完整性.引用完整性. 2.  实体完整性:能够唯一标识表中的第一个记录. 保证方法有主键约束.标识约束.唯一约束. 主键约束与唯一约束添加的基本语法 Alter  table  表名 addconstraint  约束名  约束类型  具体的约束说明 约束名的取名规则:约束类型_约束字段. 比如主键(Primary Key)约束:PK_Stu

oracle建表的时候同时创建主键,外键,注释,约束,索引

--主键create table emp (id number constraint id_pr primary key ,name1 varchar(8));create table emp9 (id number ,name1 varchar(8) ,constraint aba_pr primary key(id,name1));--外键create table emp1(id number references emp(id),name varchar(8)); --复合外键create

ORACLE: 查询(看)表的主键、外键、唯一性约束和索引

ORACLE: 查询(看)表的主键.外键.唯一性约束和索引 1.查找表的所有索引(包括索引名,类型,构成列) select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.index_name and t.table_name = i.table_name and t.table_name = 表名 2.查找表的主键(包括名称,构成列): select cu.* from user_co