AS400数据库事务处理机制

                                                                AS400数据库事务处理机制

 

  • 记录锁等待与程序处理机制

在多作业并发处理中为了保证事务的完整性,数据库通过记录锁、表锁来确保数据的正确性。一个作业在获得一条记录锁时,如果此记录已经处于锁状态,那么当前作业会如何处理呢?一般来说如果一个作业获得锁时未成功(已经被锁),那么此作业不是立即做异常处理,而是要等待一段时间,即锁等待。锁等待的时间长短主要是根据数据库的参数来确定,在AS400中锁等待的时间是可以指定到表,一般的开放平台数据库(DB2/ORCLA)是指定到数据库的。在AS400平台上锁等待时间是在编译文件(PF,LF)时指定。

如下:编译物理文件和逻辑文件时选择等待时间。

                     

一般程序中获得记录锁时需要判断记录是否被锁。

例如:

             

            

这些都是比较常用的,但这里再强调一下,出现锁不是立即进入程序的异常处理分支,而是需要等待一个锁时间后才会进行异常处理分支。如果一个程序想在出现锁时立即就进入异常处理分支,那么首先应该修改所读取表的编译参数-锁等待时间(选择合适的等待时间),并在程序中增加指示灯或(E)方式才能捕获锁锁异常,如果程序中读取数据时没有进行异常处理,那么作业将处于MSGW状态。

  • AS400数据库事务隔离级别机制

在多事务的并发处理中不同的作业(进程、线程)可能对同一条记录做增、删、改、查。在这些并发操作中常出现脏读、不可重复读、幻读这几类问题,为了解决上述的问题,数据库提出事务隔离级别,以此保证数据的正确性。在SQL关于事务隔离级别的标准中有未提交(Read Uncommitted)、读提交(Read Committed)、可重复读取(Repeatable Read),序列化(Serializable)四个级别。这四个隔离级别设置依次解决脏读、不可重复读、幻读问题。详细知识请参考数据库原理中关于事务隔离的讲解。

AS400中关于数据库的隔离级别的控制与SQL标准略有不同,就是AS400中只设置了三个隔离级别,分别是*CHG、*CS、*ALL。本文主要介绍一下*CHG和*CS使用中需要注意的地方,对于*ALL级别由于使用场景很少,所以不做介绍。

  1. *CHG

详细解释说明请参照AS400帮助说明,这里不做概念解释。下面从以下几方面说明事务级别在*CHG模式下的一些注意点。

  1. 产生锁的时机
  1. 在*CHG模式下只要F表是以“U”方式定义,那么在做读取操作时都会产生锁。例如:

              

(程序1)

锁是在“0009”(CHAIN)行产生锁。

注:只要以“U”方式定义的表在读取(READ/CHAIN)时产生锁。SETLL/SETGT不会产生锁。

  1. 应用中需要注意的地方

数据表(GACC)中存在4条记录,其中GLLTYP值分别是1,2,3,5。如果另一个作业已经将表中GLLTYP值为5的记录锁住,那程序3在做READE时将出现记录锁等待(0029行)。

          

(程序3)

注意:定位后做READ/READE时,即使没有读取到相同键值的记录同样会产生锁等待。由此说明操作记录时根据表的定义首先要获取锁,然后再判断键值是否相同。

  1. 释放锁的时机

以“U”方式打开的表,在做读取时会对记录加锁。表在定义时有COMMIT控制和没有COMMIT控制主要区别在于锁的释放点不一样。例如一下程序:

                         

(程序2)

注:记录锁是在第“0013”行产生锁,直到作业做COMMIT/

ROLLBACK时记录锁才释放。

上例中F表定义时如下(未加COMMIT)

                       

注:如果F表以这种方式定义,那么上述例子中锁是在“0013”(CHAIN)行产生,在“0019”(UPDATE)之后释放。作业退出/回收作业资源(RCLRSC)/SETON/CLOSE同样会释放锁。

  1. 锁的产生与操作符的关系

操作符与锁的关系:

操作符

打开方式

事务定义

是否产生锁

SETLL/SETGT

I

 

×

U

 

×

I

COMMIT

×

U

COMMIT

×

READE/READ

I

 

×

U

 

I

COMMIT

×

U

COMMIT

CHAIN

I

 

×

U

 

I

COMMIT

×

U

COMMIT

 

  1. *CS

下面介绍一下在*CS模式下的一些注意点。

  1. 产生锁的时机
  1. *CS模式下与*CHG模式一样只要以“U”方式定义的表都会在数据读取时产生锁(获取锁)。产生锁的时机与*CHG模式下类似,但注意在*CS模式下SETLL/SETGT也会产生锁,这点与*CHG模式不一样。
  2. *CS模式下以“I”方式打开的表,定义时如果有COMMIT控制,那么表读取时同样会产生锁。注意SETLL/SETGT/READ/READE/CHAIN都会产生锁。

    

  1. 释放锁的时机

以“U”方式或以“I”方式打开,并且定义时增加COMMIT控制,在做读取或定位时都会对记录加锁。其中,以“U”方式打开并且有COMMIT控制的,在执行COMMIT/ROLLBACK时释放锁;以“U”方式打开,但没有COMMIT控制,即使执行COMMIT/

ROLLBACK,锁依然存在,直到作业退出/执行UPDATE/回收作业资源(RCLRSC)/SETON/CLOSE。

程序参照程序1和程序2。

  1. 锁的产生与操作符的关系

操作符与锁的关系:

操作符

打开方式

事务定义

是否产生锁

SETLL/SETGT

I

 

×

U

 

I

COMMIT

U

COMMIT

READE/READ

I

 

×

U

 

I

COMMIT

U

COMMIT

CHAIN

I

 

×

U

 

I

COMMIT

U

COMMIT

 

 

 

  • 事务处理机制

事务的提交与回滚比较常用,这里主要介绍一下做ROLLBACK操作时需要格外注意的地方。

  1. 游标回滚与什么有关系

只要F表定义时增加COMMIT控制,那么做ROLLBACK时游标一定会回滚。注意不管表是以“I”方式打开或以“U”方式打开做ROLLBACK,游标一定会回滚,这点尤其需要注意,后面通过例子说明。

  1. 回滚后游标的位置

事务ROLLBACK后,相关的游标回滚的位置在哪里呢?简单说就是回滚到上条记录位置。比如做READ操作多次后,中间如果做了ROLLBACK操作,那么回滚后的游标应该定位到当前记录的上一条记录的位置。

  1. 应用中需要注意的地方
  • 回滚游标错位

     

数据表中GLLTYP值为“4”的有5条。以上程序如果在I=2时,或UPDATE时出现ERROR,将会出现记录被重复更新的情况。主要原因是做了ROLLBACK后GRCC1游标虽然是“I”方式打开,但同样会回滚到上一条记录。

注意:不管是以“U”方式或“I”方式打开表,只要有COMMIT控制回滚后游标将定位到上一条记录。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值