• 今天初步了解了informix的锁的概念


    2005-06-12 01:07:05

    分类: IT生活

    在load的时候,碰到好几次“-134 ISAM Error :no more locks”,原来是数据库中的锁的数量不够所致,后来到/informix/etc/下修改onconfig文件,把
    LOCKS的值增加到20000(原来400),问题解决。

    但在网上还看到有人用事务独占的方式,没试过。原文是这样的:
    建议先打开事务处理begin work;
    然后使用lock table tablename in exclusive mode
    然后删除delete ...
    然后commit work;

    再附上一篇关于informix数据库锁的技术的文章

    [@more@]

    Informix数据库锁的技术

    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不能马上检测到。每个数据库 
    服务器都设置锁等待的上限。如果超时,数据库服务器就认为发生了死锁且返回相关的错误代码。数据库管理员可以设置 
    和修改等待时间的上限。

     
     
  • 相关阅读:
    SQL0668N 由于表 "db2inst1.test" 上的原因代码 "3",所以不允许操作(解因为LOAD引起的LOAD暂挂状态锁)
    重装系统后,如何恢复DB2数据库?
    db2 导入导出命令大全
    解决tomcat启动时日志出现 javax.naming.NamingException: Invalid byte 1 of 1byte UTF8 sequence.的问题
    【fcntl系统调用】
    C++读书笔记之函数模板
    unix shell笔记
    用setsockopt()来控制recv()与send()的超时 【转】
    Linux守护进程的编程实现 [转]
    GDB调试core文件样例(如何定位Segment fault) 【转】
  • 原文地址:https://www.cnblogs.com/equation/p/6128040.html
Copyright © 2020-2023  润新知