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

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: DB2/Informix

2008-03-19 21:03:58


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不能马上
检测到。每个数据库  
服务器都设置锁等待的上限。如果超时,数据库服务器就认为发生了死锁且返回相关的错误代码。数据库
管理员可以设置  
和修改等待时间的上限。  
 
阅读(514) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~