Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103605154
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: DB2/Informix

2008-03-19 20:47:41


 
    INFORMIX使用锁技术解决在多用户访问数据库情况下,对同一对象访问的并发控制问题。INFORMIX 
支持复杂的、可伸缩性的锁技术。 

锁的类型 

INFORMIX有三种不同类型的锁。它们在不同的情况下使用。 

1. SHARED锁 

SHARED锁只保留对象的可读性。当锁存在时,对象不能改变。多个程序可对同个对象加SHARED锁。 

2. EXCLUSIVE锁 

只能使单个程序使用。在程序要改变对象时使用。当其他锁存在时,EXCLUSIVE锁不能使用。当使用了E 
XCLUSIVE 锁后,其他锁不能用于同一对象。 

3. PROMOTABLE锁 

实现更新的目的。PROMOTABLE锁可以放在已经有SHARED锁的记录,但不能放在已经有PROMOTABLE锁和EXCLUSIVE 
锁的地方。当记录上无其他锁(含SHARED 锁)情况下,这时在程序准备改变锁的记录时,PROMOTABLE锁可以提 
升为EXCLUSIVE锁。如果在已有SHARED锁的记录上设置了PROMOTABLE锁,在PROMOTABLE锁可以提升到EXCLUSIVE锁 
之前需要删除SHARED 锁。PROMOTABLE锁只能在INFORMIX Universal Server中支持。 

锁的范围 

INFORMIX对于数据锁定提供了三种不同的方式,范围由大到小分别是数据库、表、记录级锁。使用的时机要看应 
用状况而定。 

1. 数据库级锁 

你可以用CONNECT, DATABASE, 或 CREATE DATABASE语句打开数据库。打开数据库的操作就在数据库上设置了SHARED 
锁。只要程序打开一个数据库,SHARED锁就会阻止其他程序删除数据库或在数据库上设置EXCLUSIVE锁。你可以用语 
句DATABASE database name EXCLUSIVE锁定整个数据库。若此时其他用户正在使用该数据库,该操作将返回错误。 
一旦设置了EXCLUSIVE锁,其他程序就不能打开数据库,因为打开时要放置一个SHARED锁。只有数据库关闭时,数据 
库锁才释放。你可以用DISCONNECT或CLOSE DATABASE显示地处理,也可以运行其他的DATABASE语句隐含的处理。一般 
数据库级EXCLUSIVE锁是独占数据库资源,防止其他程序访问数据库。它使得程序非常简单,不会产生并发效果。常 
用在非高峰时期要改变大量数据时如数据库备份过程。 

2. 表级锁 

INFORMIX提供两种模式表级锁:EXCLUSIVE MODE 和SHARE MODE。你可以锁整个表。在某些情况下,这个操作是自动 
进行。当INFORMIX处理下列语句时,一般锁整个的表:ALTER INDEX 、ALTER TABLE 、CREATE INDEX、DROP INDEX 、 
RENAME COLUMN、RENAME TABLE 。该语句结束或事务结束会释放该锁。在某些查询语句中,INFORMIX也自动锁整个表。 
你可以用LOCK TABLE语句显示地锁整个表。该语句允许你对整个表设置EXCLUSIVE锁或SHARED锁。当你程序从表中读取 
数据时,SHARED锁防止表中数据更新。INFORMIX Universal Server 通过设置隔离级别实现更大程度并发数据保护。 
表级EXCLUSIVE锁防止对同个表的并发使用。因此,如果其他许多程序要使用该表时,系统性能会受到严重影响。类 
似数据库级EXCLUSIVE锁,表级EXCLUSIVE锁常用在非高峰时期要改变大量数据时。例如,有些应用在高峰期间并不更 
新表,它们可以在非高峰期间定期以批处理方式更新。 

通过UNLOCK TABLE table name 解除锁。当存在事务时,事务结束时解除锁。 

3. 记录级、页级、键字级锁 

表的一个记录是可设置锁的最小对象。一个程序可以锁一个记录或记录的集合,同时其他程序可以操作同一个表的其 
他记录。Universal Server 以磁盘页面(disk pages)为单位存储数据。一个磁盘页面包含一个或多个记录。在有 
些情况下,页级锁比单个锁更好些。其他数据库服务器可能不存在页级、键字级锁。 

在Universal Server上,当你创建表时,你可以选择使用记录级锁或页级锁。其他的数据库服务器不提供这种选择。 
页级、记录级锁有相同的效果。当Universal Server需要锁一个记录时,根据表创建时的锁模式,锁这个记录或记录 
所在的页面。在一定情况下,数据库服务器需要锁一个不存在的记录。它的效果相当于在记录将要存在的地方放一个 
锁。当表使用记录锁时,对假想的记录使用键字锁。当表使用页级锁时,含有或可能含有键字的索引页将被设置键级锁。 
锁的时期 

程序控制数据库级锁的时期。数据库关闭时,数据库锁级也就释放。表级、记录级、索引级锁的时期依赖于使用的SQL 
语句以及是否使用事务。如果数据库没有使用事务,也就是说,事务日志不存在并且你没有使用COMMIT WORK语句,当 
运行UNLOCK TABLE语句时,表级锁就释放。当使用了事务时,事务结束,表级、记录级、索引级锁都释放。修改时锁的 
处理 

当数据库服务器通过一个更新游标取一条记录时,它在该记录上设置一个PROMOTABLE锁。如果这个动作成功,数据库服 
务器知道其他程序不能改变此记录。因为PROMOTABLE锁不是独占的,其他程序能够继续读这条记录。由于在取此记录的 
程序执行UPDATE、DELETE语句或简单地取下一条记录之前,它可能花一些时间。这样就提高了性能。当它改变一个记录 
时,数据库服务器在这条记录上设置一个EXCLUSIVE锁。如果它已经有一个PROMOTABLE锁,它将锁改为EXCLUSIVE状态。 

EXCLUSIVE锁的时期依赖于是否使用事务。如果没有使用事务,被修改的记录写到磁盘上就会释放该锁。当使用了事务时, 
锁就会保持到事务的结束。这个动作防止其他程序使用可能回滚到原来状态的记录。 

当使用了事务时,只要删除记录键级锁就会设置。使用键级锁解决下列错误:程序A删除一个记录,程序B插入有同样键的 
记录。程序A回滚事务,使数据库服务器恢复了删除的记录,这时程序B插入的记录怎么办?通过锁索引,数据库服务器等 
到程序A提交事务时才插入记录。 

由于 Universal Server数据库服务器管理自己的锁,所以它能提供不同类型的锁。其他的数据库服务器是通过操作系统 
的特性实现锁,所以不能提供多种选择。有些操作系统通过操作系统服务方式向外提供锁函数。在这些系统,数据库支持 
SET LOCK MODE语句。而有些操作系统不支持内核级的特性,数据库这时通过在数据库目录下产生小文件实现锁。这些文 
件带有.lok后缀。如果你的程序使用单个SELECT语句或没有用FOR UPDATE声明的游标提取一个记录,此记录不管是否被 
一个未完成的交易上锁会马上被提取。这样能产生最好的性能。当你使用FOR UPDATE声明的游标时,它在提取前将当前 
记录上锁。如果当前记录已经有锁,随作选择模式的不同,程序会等待或返回错误。当取下一个记录时,数据库看当前 
记录是否更新(使用带WHERE CURRENT OF 的UPDATE  


锁的模式 

锁的模式决定程序遇到被锁的数据会产生怎样的结果。当程序要提取或修改一个上锁的记录时,会有下面几种情况: 

1、 数据库马上通过SQLCODE变量或SQLSTATE结构给程序返回一个错误代码。 

2、 在数据解锁前,数据库将程序挂起。 

3、数据库将程序挂起一段时间。如果锁还未解,数据库给程序返回一个错误代码。 

你可以通过SET LOCK MODE模式选择以上结果。 

如果你喜欢程序等待(对大多数程序而言这是最好的选择),运行下列语句:SET LOCK MODE TO WAIT。 

当设置了锁模式后,程序常忽视其他并发程序的存在性。如果程序需要访问其他程序已上锁的记录时,它等待别的程序 
解锁,然后继续。延迟的时间常不可预测。 

等待解锁不利的一面就是可能会等待很长时间。如果不能接受很长延迟,程序可以运行下列语句:SET LOCK MODE TO  
NOT WAIT选择不等待。当程序需要一个锁记录时,它马上返回一个错误代码,且当前的SQL语句终止。这时,程序必须回 
滚当前的交易再试一次。程序开始时,数据库初始设置为不等待。 

当你使用UNIVERSAL SERVER时,你有另外的选择。你可以让数据库设置等待时间的上限。你可用下列语句:SETLOCK MODE  
TO WAIT 18让数据库有18秒等待上限。若期间锁还没有解开,将返回错误代码。 

在每个程序都选择了锁等待模式情况下,有可能出现死锁。死锁是程序之间相互阻塞,每个程序在其他程序要访问的对象 
上设置了锁。UNIVERSAL SERVER在单个网络服务器情况下会马上检测到死锁。如果程序选择了锁等待模式,通过给程序返 
回错误代码,你就知道你遇到了死锁。而在多个数据库服务器的情况下,UNIVERSAL SERVER不能马上检测到。每个数据库 
服务器都设置锁等待的上限。如果超时,数据库服务器就认为发生了死锁且返回相关的错误代码。数据库管理员可以设置 
和修改等待时间的上限。
阅读(778) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~