牛新庄, IBM官方高级培训讲师

http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0512niuxzh/

2005 年 12 月 26 日

在实际的生产运行环境中,笔者在国内很多客户现场都看到开发人员和系统管理人员遇到很多有关于锁而引起的性能问题,进而被多次问起DB2和Oracle中锁的区别比较问题,笔者根据自己在工作中对DB2和Oracle数据库的使用经验积累写下这篇文章。

1 引言

在关系数据库(DB2,Oracle,Sybase,Informix和SQL Server)最小的恢复和交易单位为一个事务(Transactions),事务具有ACID(原子性,一致性,隔离性�

表是由行组成的,当我们向某个表加锁时,一方面需要检查该锁的申请是否与原有的表级锁相容;另一方面,还要检查该锁是否与表中的每一行上的锁相容。比如一个事务要在一个表上加S锁,如果表中的一行已被另外的事务加了X锁,那么该锁的申请也应被阻塞。如果表中的数据很多,逐行检查锁标志的开销将很大,系统的性能将会受到影响。为了解决这个问题,可以在表级引入新的锁类型来表示其所属行的加锁情况,这就引出了"意向锁"的概念。

意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。如:对表中的任一行加锁时,必须先对它所在的表加意向锁,然后再对该行加锁。这样一来,事务对表加锁时,就不再需要检查表中每行记录的锁标志位了,系统效率得以大大提高。

3.2.2 意向锁的类型

由两种基本的锁类型(S锁、X锁),可以自然地派生出两种意向锁:

意向共享锁(Intent Share Lock,简称IS锁):如果要对一个数据库对象加S锁,首先要对其上级结点加IS锁,表示它的后裔结点拟(意向)加S锁;

意向排它锁(Intent Exclusive Lock,简称IX锁):如果要对一个数据库对象加X锁,首先要对其上级结点加IX锁,表示它的后裔结点拟(意向)加X锁。

另外,基本的锁类型(S、X)与意向锁类型(IS、IX)之间还可以组合出新的锁类型,理论上可以组合出4种,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不难看出,实际上只有S+IX有新的意义,其它三种组合都没有使锁的强度得到提高(即:S+IS=S,X+IS=X,X+IX=X,这里的"="指锁的强度相同)。所谓锁的强度是指对其它锁的排斥程度。

这样我们又可以引入一种新的锁的类型:

共享意向排它锁(Shared Intent Exclusive Lock,简称SIX锁):如果对一个数据库对象加SIX锁,表示对它加S锁,再加IX锁,即SIX=S+IX。例如:事务对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别行(所以要对该表加IX锁)。

这样数据库对象上所加的锁类型就可能有5种:即S、X、IS、IX、SIX。

具有意向锁的多粒度封锁方法中任意事务T要对一个数据库对象加锁,必须先对它的上层结点加意向锁。申请封锁时应按自上而下的次序进行;释放封锁时则应按自下而上的次序进行;具有意向锁的多粒度封锁方法提高了系统的并发度,减少了加锁和解锁的开销。

3.3 Oracle的TM锁(表级锁)

Oracle的DML锁(数据锁)正是采用了上面提到的多粒度封锁方法,其行级锁虽然只有一种(即X锁),但其TM锁(表级锁)类型共有5种,分别称为共享锁(S锁)、排它锁(X锁)、行级共享锁(RS锁)、行级排它锁(RX锁)、共享行级排它锁(SRX锁),与上面提到的S、X、IS、IX、SIX相对应。需要注意的是,由于Oracle在行级只提供X锁,所以与RS锁(通过SELECT … FOR UPDATE语句获得)对应的行级锁也是X锁(但是该行数据实际上还没有被修改),这与理论上的IS锁是有区别的。锁的兼容性是指当一个应用程序在表(行)上加上某种锁后,其他应用程序是否能够在表(行)上加上相应的锁,如果能够加上,说明这两种锁是兼容的,否则说明这两种锁不兼容,不能对同一数据对象并发存取。

下表为Oracle数据库TM锁的兼容矩阵(Y=Yes,表示兼容的请求; N=No,表示不兼容的请求;-表示没有加锁请求):

表五:Oracle数据库TM锁的相容矩阵

一方面,当Oracle执行SELECT…FOR UPDATE、INSERT、UPDATE、DELETE等DML语句时,系统自动在所要操作的表上申请表级RS锁(SELECT…FOR UPDATE)或RX锁(INSERT、UPDATE、DELETE),当表级锁获得后,系统再自动申请TX锁,并将实际锁定的数据行的锁标志位置位(指向该TX锁);另一方面,程序或操作人员也可以通过LOCK TABLE语句来指定获得某种类型的TM锁。下表是笔者总结了Oracle中各SQL语句产生TM锁的情况:

表六:Oracle数据库TM锁小结

我们可以看到,通常的DML操作(SELECT…FOR UPDATE、INSERT、UPDATE、DELETE),在表级获得的只是意向锁(RS或RX),其真正的封锁粒度还是在行级;另外,Oracle数据库的一个显著特点是,在缺省情况下,单纯地读数据(SELECT)并不加锁,Oracle通过回滚段(Rollback segment)来保证用户不读"脏"数据。这些都提高了系统的并发程度。

由于意向锁及数据行上锁标志位的引入,减小了Oracle维护行级锁的开销,这些技术的应用使Oracle能够高效地处理高度并发的事务请求。


回页首

4 DB2多粒度封锁机制的监控

在DB2中对锁进行监控主要有两种方式,第一种方式是快照监控,第二种是事件监控方式。

4.1 快照监控方式

当使用快照方式进行锁的监控前,必须把监控锁的开关打开,可以从实例级别和会话级别打开,具体命令如下:

db2 update dbm cfg using dft_mon_lock on(实例级别)
db2 update monitor switches using lock on(会话级别,推荐使用)

当开关打开后,可以执行下列命令来进行锁的监控

db2 get snapshot for locks on ebankdb(可以得到当前数据库中具体锁的详细信息)
db2 get snapshot for locks on ebankdb
Fri Aug 15 15:26:00 JiNan 2004(红色为锁的关键信息)


             Database Lock Snapshot
Database name                              = DEV
Database path                              = /db2/DEV/db2dev/NODE0000/SQL00001/
Input database alias                       = DEV
Locks held                                 = 49
Applications currently connected           = 38
Agents currently waiting on locks          = 6
Snapshot timestamp                         = 08-15-2003 15:26:00.951134
Application handle                         = 6
Application ID                             = *LOCAL.db2dev.030815021007
Sequence number                            = 0001
Application name                           = disp+work
Authorization ID                           = SAPR3
Application status                         = UOW Waiting
Status change time                         =
Application code page                      = 819
Locks held                                 = 0
Total wait time (ms)                       = 0
Application handle                         = 97
Application ID                             = *LOCAL.db2dev.030815060819
Sequence number                            = 0001
Application name                           = tp
Authorization ID                           = SAPR3
Application status                         = Lock-wait
Status change time                         = 08-15-2003 15:08:20.302352
Application code page                      = 819
Locks held                                 = 6
Total wait time (ms)                       = 1060648Subsection waiting for lock              = 0ID of agent holding lock                 = 100Application ID holding lock              = *LOCAL.db2dev.030815061638Node lock wait occurred on               = 0Lock object type                         = RowLock mode                                = Exclusive Lock (X)Lock mode requested                      = Exclusive Lock (X)Name of tablespace holding lock          = PSAPBTABDSchema of table holding lock             = SAPR3Name of table holding lock               = TPLOGNAMESLock wait start timestamp                = 08-15-2003 15:08:20.302356Lock is a result of escalation           = NO
List Of LocksLock Object Name            = 29204Node number lock is held at = 0Object Type                 = TableTablespace Name             = PSAPBTABDTable Schema                = SAPR3Table Name                  = TPLOGNAMESMode                        = IXStatus                      = GrantedLock Escalation             = NO 

db2 get snapshot for database on dbname |grep -i locks(UNIX,LINUX平台)


Locks held currently                       = 7
Lock waits                                 = 75
Time database waited on locks (ms)         = 82302438
Lock list memory in use (Bytes)            = 20016
Deadlocks detected                         = 0
Lock escalations                           = 8
Exclusive lock escalations                 = 8
Agents currently waiting on locks          = 0
Lock Timeouts                              = 20

db2 get snapshot for database on dbname |find /i "locks"(NT平台)
db2 get snapshot for locks for applications agentid 45(注:45为应用程序句柄)


 Application handle                         = 45
Application ID                             = *LOCAL.db2dev.030815021827
Sequence number                            = 0001
Application name                           = tp
Authorization ID                           = SAPR3
Application status                         = UOW Waiting
Status change time                         =
Application code page                      = 819
Locks held                                 = 7
Total wait time (ms)                       = 0
List Of LocksLock Object Name            = 1130185838Node number lock is held at = 0Object Type                 = Key ValueTablespace Name             = PSAPBTABDTable Schema                = SAPR3Table Name                  = TPLOGNAMESMode                        = XStatus                      = GrantedLock Escalation             = NOLock Object Name            = 14053937Node number lock is held at = 0Object Type                 = RowTablespace Name             = PSAPBTABDTable Schema                = SAPR3Table Name                  = TPLOGNAMESMode                        = XStatus                      = GrantedLock Escalation             = NO

也可以执行下列表函数(注:在DB2 V8之前只能通过命令,DB2 V8后可以通过表函数,推荐使用表函数来进行锁的监控)

db2 select * from table(snapshot_lock('DBNAME',-1)) as locktable监控锁信息
db2 select * from table(snapshot_lockwait('DBNAME',-1) as lock_wait_table监控应用程序锁等待的信息

4.2 事件监控方式:

当使用事件监控器进行锁的监控时候,只能监控死锁(死锁的产生是因为由于锁请求冲突而不能结束事务,并且该请求冲突不能够在本事务内解决。通常是两个应用程序互相持有寒�永久性)特征。关系数据库为了确保并发用户在存取同一数据库对象时的正确性(即无丢失更新、可重复读、不读"脏"数据,无"幻像"读),数据库中引入了并发(锁)机制。基本的锁类型有两种:排它锁(Exclusive locks记为X锁)和共享锁(Share locks记为S锁)。

排它锁:若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。

共享锁:若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。

2 DB2 多粒度封锁机制介绍

2.1 锁的对象

DB2支持对表空间、表、行和索引加锁(大型机上的数据库还可以支持对数据页加锁)来保证数据库的并发完整性。不过在考虑用户应用程序的并发性的问题上,通常并不检查用于表空间和索引的锁。该类问题分析的焦点在于表锁和行锁。

2.2 锁的策略

DB2可以只对表进行加锁,也可以对表和表中的行进行加锁。如果只对表进行加锁,则表中所有的行都受到同等程度的影响。如果加锁的范围针对于表及下属的行,则在对表加锁后,相应的数据行上还要加锁。究竟应用程序是对表加行锁还是同时加表锁和行锁,是由应用程序执行的命令和系统的隔离级别确定。

2.2.1 DB2表锁的模式

DB2在表一级加锁可以使用以下加锁方式:

表一:DB2数据库表锁的模式

下面对几种表锁的模式进一步加以阐述:

IS、IX、SIX方式用于表一级并需要行锁配合,他们可以阻止其他应用程序对该表加上排它锁。

  • 如果一个应用程序获得某表的IS锁,该应用程序可获得某一行上的S锁,用于只读操作,同时其他应用程序也可以读取该行,或是对表中的其他行进行更改。
  • 如果一个应用程序获得某表的IX锁,该应用程序可获得某一行上的X锁,用于更改操作,同时其他应用程序可以读取或更改表中的其他行。
  • 如果一个应用程序获得某表的SIX锁,该应用程序可以获得某一行上的X锁,用于更改操作,同时其他应用程序只能对表中其他行进行只读操作。

S、U、X和Z方式用于表一级,但并不需要行锁配合,是比较严格的表加锁策略。

  • 如果一个应用程序得到某表的S锁。该应用程序可以读表中的任何数据。同时它允许其他应用程序获得该表上的只读请求锁。如果有应用程序需要更改读该表上的数据,必须等S锁被释放。
  • 如果一个应用程序得到某表的U锁,该应用程序可以读表中的任何数据,并最终可以通过获得表上的X锁来得到对表中任何数据的修改权。其他应用程序只能读取该表中的数据。U锁与S锁的区别主要在于更改的意图上。U锁的设计主要是为了避免两个应用程序在拥有S锁的情况下同时申请X锁而造成死锁的。
  • 如果一个应用程序得到某表上的X锁,该应用程序可以读或修改表中的任何数据。其他应用程序不能对该表进行读或者更改操作。
  • 如果一个应用程序得到某表上的Z锁,该应用程序可以读或修改表中的任何数据。其他应用程序,包括未提交读程序都不能对该表进行读或者更改操作。

IN锁用于表上以允许未提交读这一概念。

2.2.2 DB2行锁的模式

除了表锁之外,DB2还支持以下几种方式的行锁。

表二:DB2数据库行锁的模式

2.2.3 DB2锁的兼容性

表三:DB2数据库表锁的相容矩阵

表四:DB2数据库行锁的相容矩阵

下表是笔者总结了DB2中各SQL语句产生表锁的情况(假设缺省的隔离级别为CS):

2.3 DB2锁的升级

每个锁在内存中都需要一定的内存空间,为了减少锁需要的内存开销,DB2提供了锁升级的功能。锁升级是通过对表加上非意图性的表锁,同时释放行锁来减少锁的数目,从而达到减少锁需要的内存开销的目的。锁升级是由数据库管理器自动完成的,有两个数据库的配置参数直接影响锁升级的处理:

locklist--在一个数据库全局内存中用于锁存储的内存。单位为页(4K)。

maxlocks--一个应用程序允许得到的锁占用的内存所占locklist大小的百分比。

锁升级会在这两种情况下被触发:

  • 某个应用程序请求的锁所占用的内存空间超出了maxlocks与locklist的乘积大小。这时,数据库管理器将试图通过为提出锁请求的应用程序申请表锁,并释放行锁来节省空间。
  • 在一个数据库中已被加上的全部锁所占的内存空间超出了locklist定义的大小。这时,数据库管理器也将试图通过为提出锁请求的应用程序申请表锁,并释放行锁来节省空间。
  • 锁升级虽然会降低OLTP应用程序的并发性能,但是锁升级后会释放锁占有内存并增大可用的锁的内存空间。

锁升级是有可能会失败的,比如,现在一个应用程序已经在一个表上加有IX锁,表中的某些行上加有X锁,另一个应用程序又来请求表上的IS锁,以及很多行上的S锁,由于申请的锁数目过多引起锁的升级。数据库管理器试图为该应用程序申请表上的S锁来减少所需要的锁的数目,但S锁与表上原有的IX锁冲突,锁升级不能成功。

如果锁升级失败,引起锁升级的应用程序将接到一个-912的SQLCODE。在锁升级失败后,DBA应该考虑增加locklist的大小或者增大maxlocks的百分比。同时对编程人员来说可以在程序里对发生锁升级后程序回滚后重新提交事务(例如:if sqlca.sqlcode=-912 then rollback and retry等)。


回页首

3 Oracle 多粒度锁机制介绍

根据保护对象的不同,Oracle数据库锁可以分为以下几大类:

(1) DML lock(data locks,数据锁):用于保护数据的完整性;

(2) DDL lock(dictionary locks,字典锁):用于保护数据库对象的结构(例如表、视图、索引的结构定义);

(3) Internal locks 和latches(内部锁与闩):保护内部数据库结构;

(4) Distributed locks(分布式锁):用于OPS(并行服务器)中;

(5) PCM locks(并行高速缓存管理锁):用于OPS(并行服务器)中。

在Oracle中最主要的锁是DML(也可称为data locks,数据锁)锁。从封锁粒度(封锁对象的大小)的角度看,Oracle DML锁共有两个层次,即行级锁和表级锁。

3.1 Oracle的TX锁(行级锁、事务锁)

许多对Oracle不太了解的技术人员可能会以为每一个TX锁代表一条被封锁的数据行,其实不然。TX的本义是Transaction(事务),当一个事务第一次执行数据更改(Insert、Update、Delete)或使用SELECT… FOR UPDATE语句进行查询时,它即获得一个TX(事务)锁,直至该事务结束(执行COMMIT或ROLLBACK操作)时,该锁才被释放。所以,一个TX锁,可以对应多个被该事务锁定的数据行(在我们用的时候多是启动一个事务,然后SELECT… FOR UPDATE NOWAIT)。

在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定。Oracle不像DB2那样,建立一个链表来维护每一行被加锁的数据,这样就大大减小了行级锁的维护开销,也在很大程度上避免了类似DB2使用行级锁时经常发生的锁数量不够而进行锁升级的情况。数据行上的锁标志一旦被置位,就表明该行数据被加X锁,Oracle在数据行上没有S锁。

3.2 TM锁(表级锁)

3.2.1 意向锁的引出

�方所需要的锁,在得不到自己所需要的锁的情况下,也不会释放现有的锁)的情况,具体步骤如下:

db2 create event monitor dlock for deadlocks with details write to file '$HOME/dir'
db2 set event monitor dlock state 1
db2evmon -db dbname -evm dlock看具体的死锁输出(如下图)


      Deadlocked Connection ...Deadlock ID:   4Participant no.: 1Participant no. holding the lock: 2Appl Id: G9B58B1E.D4EA.08D387230817Appl Seq number: 0336Appl Id of connection holding the lock: G9B58B1E.D573.079237231003Seq. no. of connection holding the lock: 0126Lock wait start time: 06/08/2005 08:10:34.219490Lock Name       : 0x000201350000030E0000000052Lock Attributes : 0x00000000Release Flags   : 0x40000000Lock Count      : 1Hold Count      : 0Current Mode    : NS  - Share (and Next Key Share)Deadlock detection time: 06/08/2005 08:10:39.828792Table of lock waited on      : ORDERSSchema of lock waited on     : DB2INST1Tablespace of lock waited on : USERSPACE1Type of lock: RowMode of lock: NS  - Share (and Next Key Share)Mode application requested on lock: X   - ExclusiveNode lock occured on: 0Lock object name: 782Application Handle: 298Deadlocked Statement:Type     : DynamicOperation: ExecuteSection  : 34Creator  : NULLIDPackage  : SYSSN300Cursor   : SQL_CURSN300C34Cursor was blocking: FALSEText     : UPDATE ORDERS  SET TOTALTAX = ?, TOTALSHIPPING = ?, LOCKED = ?, TOTALTAXSHIPPING = ?, STATUS = ?, FIELD2 = ?, TIMEPLACED = ?, FIELD3 = ?, CURRENCY = ?, SEQUENCE = ?, TOTALADJUSTMENT = ?, ORMORDER = ?, SHIPASCOMPLETE = ?, PROVIDERORDERNUM = ?, TOTALPRODUCT = ?, DESCRIPTION = ?, MEMBER_ID = ?, ORGENTITY_ID = ?, FIELD1 = ?, STOREENT_ID = ?, ORDCHNLTYP_ID = ?, ADDRESS_ID = ?, LASTUPDATE = ?, COMMENTS = ?, NOTIFICATIONID = ? WHERE ORDERS_ID = ?List of Locks:Lock Name                   : 0x000201350000030E0000000052Lock Attributes             : 0x00000000Release Flags               : 0x40000000Lock Count                  : 2Hold Count                  : 0Lock Object Name            : 782Object Type                 : RowTablespace Name             : USERSPACE1Table Schema                : DB2INST1Table Name                  : ORDERSMode                        : X   - ExclusiveLock Name                   : 0x00020040000029B30000000052Lock Attributes             : 0x00000020Release Flags               : 0x40000000Lock Count                  : 1Hold Count                  : 0Lock Object Name            : 10675Object Type                 : RowTablespace Name             : USERSPACE1Table Schema                : DB2INST1Table Name                  : BKORDITEMMode                        : X   - Exclusive(略去后面信息)

回页首

5 Oracle 多粒度封锁机制的监控

为了监控Oracle系统中锁的状况,我们需要对几个系统视图有所了解:

5.1 v$lock视图

v$lock视图列出当前系统持有的或正在申请的所有锁的情况,其主要字段说明如下:

表七:v$lock视图主要字段说明

其中在TYPE字段的取值中,本文只关心TM、TX两种DML锁类型;

5.2 v$locked_object视图

v$locked_object视图列出当前系统中哪些对象正被锁定,其主要字段说明如下:

表八:v$locked_object视图字段说明

5.3 Oracle锁监控脚本

根据上述系统视图,可以编制脚本来监控数据库中锁的状况。

5.3.1 showlock.sql

第一个脚本showlock.sql,该脚本通过连接v$locked_object与all_objects两视图,显示哪些对象被哪些会话锁住:


/* showlock.sql */
column o_name format a10
column lock_type format a20
column object_name format a15
select rpad(oracle_username,10) o_name,session_id sid,
decode(locked_mode,0,'None',1,'Null',2,'Row share',
3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type,
object_name ,xidusn,xidslot,xidsqn
from v$locked_object,all_objects
where v$locked_object.object_id=all_objects.object_id;
5.3.2   showalllock.sql

第二个脚本showalllock.sql,该脚本主要显示当前所有TM、TX锁的信息;


/* showalllock.sql */
select sid,type,id1,id2,
decode(lmode,0,'None',1,'Null',2,'Row share',
3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')
lock_type,request,ctime,block
from v$lock
where TYPE IN('TX','TM');

回页首

6 DB2 多粒度封锁机制示例

以下示例均运行在DB2 UDB中,适用所有数据库版本。首先打开三个命令行窗口(DB2 CLP),其中两个(以下用SESS#1、SESS#2表示)以db2admin用户连入数据库,以操作SAMPLE库中提供的示例表(employee);另一个(以下用SESS#3表示)以db2admin用户连入数据库,对执行的每一种类型的SQL语句监控加锁的情况;希望读者通过这种方式对每一种类型的SQL语句监控加锁的情况。(因为示例篇幅很大,笔者在此就不做了,建议读者用类似方法验证加锁情况)


/home/db2inst1>db2 +c update employee set comm=9999(SESS#1)
/home/db2inst1>db2 +c select * from employee(SESS#2处于lock wait)
/home/db2inst1>db2 +c get snapshot for locks on sample(SESS#3监控加锁情况)

注:db2 +c为不自动提交(commit)SQL语句,也可以通过 db2 update command options using c off关闭自动提交(autocommit,缺省是自动提交)


回页首

7 总结

总的来说,DB2的锁和Oracle的锁主要有以下大的区别:

1.Oracle通过具有意向锁的多粒度封锁机制进行并发控制,保证数据的一致性。其DML锁(数据锁)分为两个层次(粒度):即表级和行级。通常的DML操作在表级获得的只是意向锁(RS或RX),其真正的封锁粒度还是在行级;DB2也是通过具有意向锁的多粒度封锁机制进行并发控制,保证数据的一致性。其DML锁(数据锁)分为两个层次(粒度):即表级和行级。通常的DML操作在表级获得的只是意向锁(IS,SIX或IX),其真正的封锁粒度也是在行级;另外,在Oracle数据库中,单纯地读数据(SELECT)并不加锁,这些都提高了系统的并发程度,Oracle强调的是能够"读"到数据,并且能够快速的进行数据读取。而DB2的锁强调的是"读一致性",进行读数据(SELECT)时会根据不同的隔离级别(RR,RS,CS)而分别加S,IS,IS锁,只有在使用UR隔离级别时才不加锁。从而保证不同应用程序和用户读取的数据是一致的。

2. 在支持高并发度的同时,DB2和Oracle对锁的操纵机制有所不同:Oracle利用意向锁及数据行上加锁标志位等设计技巧,减小了Oracle维护行级锁的开销,使其在数据库并发控制方面有着一定的优势。而DB2中对每个锁会在锁的内存(locklist)中申请分配一定字节的内存空间,具体是X锁64字节内存,S锁32字节内存(注:DB2 V8之前是X锁72字节内存而S锁36字节内存)。

3. Oracle数据库中不存在锁升级,而DB2数据库中当数据库表中行级锁的使用超过locklist*maxlocks会发生锁升级。

4. 在Oracle中当一个session对表进行insert,update,delete时候,另外一个session仍然可以从Orace回滚段或者还原表空间中读取该表的前映象(before image); 而在DB2中当一个session对表进行insert,update,delete时候,另外一个session仍然在读取该表数据时候会处于lock wait状态,除非使用UR隔离级别可以读取第一个session的未提交的值;所以Oracle同一时刻不同的session有读不一致的现象,而DB2在同一时刻所有的session都是"读一致"的。


回页首

8 结束语

DB2中关于并发控制(锁)的建议

1.正确调整locklist,maxlocks,dlchktime和locktimeout等和锁有关的数据库配置参数(locktimeout最好不要等于-1)。如果锁内存不足会报SQL0912错误而影响并发。

2.写出高效而简洁的SQL语句(非常重要)。

3.在业务逻辑处理完后尽可能快速commit释放锁。

4.对引起锁等待(SQL0911返回码68)和死锁(SQL0911返回码2)的SQL语句创建最合理的索引(非常重要,尽量创建复合索引和包含索引)。

5.使用 altER TABLE 语句的 LOCKSIZE 参数控制如何在持久基础上对某个特定表进行锁定。检查syscat.tables中locksize字段,尽量在符合业务逻辑的情况下,每个表中该字段为"R"(行级锁)。

6.根据业务逻辑使用正确的隔离级别(RR,RS,CS和UR)。

7.当执行大量更新时,更新之前,在整个事务期间锁定整个表(使用 SQL LOCK TABLE 语句)。这只使用了一把锁从而防止其它事务进行这些更新,但是对于其他用户它的确减少了数据并发性。


回页首

免责声明和公开声明

本文所述观点是基于作者个人对相关产品的理解,并不代表 IBM 的官方观点,IBM 不对本文中的信息负责。


回页首

回页首

关于作者

牛新庄博士是IBM官方高级培训讲师,于2002年获IBM杰出软件专家奖,是《程序员》,《电脑编程与维护》等杂志数据库专栏作家,是很多公司的技术顾问,他拥有OCP,AIX,DB2,HP-UX,MQ,CICS和WebSphere等二十多项国际认证。曾经帮助工农商建招交六大行、上海移动、青岛海尔、云南红塔、江苏电力公司等公司做过问题诊断、性能调优和技术支持,他经常往返于国内大中城市解决数据库技术难题,有着丰富的理论和实践经验。

DB2和 Oracle的并发控制(锁)比较相关推荐

  1. db2与oracle的区别 锁,db2和oracle语句区别

    1.取前N条记录 Oracle:Select * from TableName where rownum <= N; DB2:Select * from TableName fetch firs ...

  2. oracle无会话锁表,深入浅出oracle锁 原理篇 停止无反应的sql会话

    在现代的多用户多任务系统中,必然会出现多个用户同时访问共享的某个对象,这个对象可能是表,行,或者内存结构,为了解决多个用户并发性访问带来的数据的安全性,完整性及一致性问题,必须要有一种机制,来使对这些 ...

  3. 解决oracle分布式锁,oracle DLM分布式锁技术

    oracle DLM分布式锁技术 RAC本质还是一个数据库,采用了分布式锁管理器.DLM作用是协调实例间对资源的竞争访问,而实例内部的竞争和单实例一样.在RAC数据库中一个节点想要修改数据,都需要想D ...

  4. RAC学习笔记(2)-DB2和Oracle体系结构

    阅读RAC和DB2的区别(资料来源为Oracle方面,所以可能有偏颇,我会再去Ibm那里找Db2与Oracle的对比,呵呵) 几个体系结构 Shared Nothing 结构 https://p-bl ...

  5. oracle的乐观锁和悲观锁

    一.问题引出 1. 假设当当网上用户下单买了本书,这时数据库中有条订单号为001的订单,其中有个status字段是'有效',表示该订单是有效的: 2. 后台管理人员查询到这条001的订单,并且看到状态 ...

  6. oracle text db2,从Oracle 到DB2(一)

    在实际的软件项目的开发过程中,特别是在企业的应用系统集成(EAI)项目中广大开发人员经常遇到不同关系型数据库之间的数据移植问题.笔者根据自己在工作中的不同数据库数据移植的经验经过通用化的java应用程 ...

  7. Oracle的悲观锁和乐观锁

    为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突.为了解决这个问题,大多数数据库用的方法就是数据的锁定. 数据的锁定分为两种方法,第一种叫做悲观锁,第二种叫做乐观锁.什么叫 ...

  8. Oracle关于TX锁的一个有趣的问题

    前阵子有一个网友在群里问了一个关于Oracle数据库的TX锁问题,问题原文如下: 请教一个问题: 两个会话执行不同的delete语句,结果都是删除同一个行.先执行的会话里where条件不加索引走全表扫 ...

  9. 并发执行变成串行_大神浅谈数据库并发控制 锁和 MVCC

    在学习几年编程之后,你会发现所有的问题都没有简单.快捷的解决方案,很多问题都需要权衡和妥协,而本文介绍的就是数据库在并发性能和可串行化之间做的权衡和妥协 - 并发控制机制.  如果数据库中的所有事务 ...

最新文章

  1. GAN:「太难的部分我就不生成了,在下告退」
  2. PL/SQL 存储过程学习2 条件语句
  3. java基础IO流使用读取一个文件中的文字输出到控制台上
  4. html质感阴影_CSS3 阴影(text-shadow)
  5. 运用Java对微信公众平台二次开发技术——开发者模式接入
  6. PDF打印机常见问题汇总
  7. Redhat开机丢失引导
  8. 电设——开关电源——LM2596
  9. python怎么过滤标点符号大全_一行Python代码过滤标点符号等特殊字符
  10. 开车二十年后得到的真实的26条教训!开车的人一定看看!
  11. 计算机五年计划个人,教师个人五年发展规划
  12. 【ROS基础】ROS_c++ 语法记录
  13. 【橙子】C#Unity--2D迷宫
  14. android 4.3 nfc,nfc读卡在android 4.4以上与4.4以下写法的区别
  15. 计算机中顺序结构,2.逻辑结构(一):顺序结构
  16. ora数据库常用命令
  17. 13个Python最佳编程技巧,越早知道越好
  18. (原創) 如何將DE2_70_TV範例加上Sobel Edge Detector? (SOC) (Verilog) (Image Processing) (DE2-70)...
  19. 详谈为什么要写测试用例
  20. Excel - VBA实例: 遍历若干cell的值

热门文章

  1. Excel 日期和时间函数
  2. P1957 口算练习题 Java
  3. matlab 幅值相角裕度,伯德图分析-稳定性-及幅值和相角裕度.ppt
  4. 《Keep your Eyes on the Lane:Real-time Attention-guided Lane Detection》
  5. C语言实现-杨辉三角(详解解析-知识点总结)
  6. Flowable入门系列文章193 - 禁用批量插入和安全脚本
  7. 计算机实训报告英语,中英文打字实训的总结报告
  8. Modelsim 与Vivado联合仿真版本对应问题
  9. 大数据凉了?不,凉的是不合法数据公司
  10. flask框架和配置