荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: baty (新一代懒人), 信区: Database
标  题: 多用户操作与并发控制(ZZ)
发信站: 荔园晨风BBS站 (Sun Jul 21 11:47:44 2002), 转信

以前, 我们主要讨论了FoxPro在单用户状态下的使用情况。本章在此基础上重点讨
论多用户命令与网络函数、数据共享与并发控制等内容。

● 多用户命令

数据库追求的目标之一是数据共享。一个数据库可以为多个用户、 多种利用目的
服务。为了保证数据库的安全性与完整性, 对数据库的共享必须有一定的控制 。
当前的信息资源网络化, 多个用户可以通过日益发达的通信网络(或信息高速公路)
 来共享数据库的信息资源。对于数据库文件级的控制, 多个用户操作分为共享方
式和独占方式。 在打开数据库文件时分为共享方式打开和排它性打开。对于用共
享方式打开的数据库文件, 其记录也可加锁和解锁。这类操作命令有文件打开控制
和记录加锁操作。

‥ 数据库文件打开方式的控制

1. set exclusive 命令

格式: SET EXCLUSIVE ON/OFF

如果选择ON, 则表示在此命令之后所有用use命令打开的数据库文件均以排它性方
式打开。这时, 用户打开的一切数据库文件都是以独占方式使用, 此时其他用户不
能打开该文件, 若有其他用户打开已被独占方式文件的操作, 则系统显示出错信息
: File is in by anothor, 出错号为108。

封锁文件主要用于更新文件时的需要, 这样可以保证数据库记录的完整性。

对于已更新完的数据库文件可以选择OFF, 提供给其他用户使用。

2. 个别文件的排它性打开命令 use

格式: use [<文件名>] [INDEX <索引文件名表>] exclusive [alias <别名>]

该命令除了增加了保留字exclusive之外, 其它内容我们在前面已进行了具体讨论
和使用。这条命令只限于指定的一个文件以排它方式打开。

例如, set exclusive off

use D1



use D2 exclusive



use D3

该程序段表明文件D1、D3是共享打开, 而文件D2是以排它方式打开。

注意: 不能把use D2 exclusive命令理解成set exclusive on 和use D2两条命令
的合成. 在程序段中, 若将其替换, 会得出不同的系统状态。

例如, set exclusive off

use D1



set exclusive on

use D2



use D3

该程序段表示文件D1是共享打开, 而文件D2和D3是排它性打开。 显然这个程序段
的含义与上一个程序段的含义是不同的 。

‥ 记录的加锁与解锁操作

在多用户环境下, 经常需要修改当前数据库的记录。若当前文件以排它性方式打开
,则可以直接操作。如果当前文件是共享打开, 又没设置文件封锁, 则不能直接修
改记录。必须先对需要修改的记录加锁, 再修改就不会丢失修改或造成数据库数据
的不一致问题。

1. 记录的加锁与解锁控制开关

数据库文件在执行edit或change命令时, 对共享打开的文件在修改前键入
"ctrl-o",使当前记录为封锁状态, 然后更新当前记录。 对当前记录的所有字段修
改完毕后, 系统自动地将记录指针下移, 使下一条记录成为当前记录, 并且将记录
封锁状态变成未封锁状态(Record unlocked)。有时用户修改记录前面的字段而不
修改记录最后一个字段, 系统无法识别该记录已修改完毕, 就不释放当前封锁状态
,用户可以再键入"ctrl-o", 使记录解锁。

2. unlock命令

格式: UNLOCCK [ALL]

若不选择ALL, 仅用unlock, 则表示当前所选择工作区中正在封锁的文件或记录解
锁。如果选择ALL项, 则表示解除该用户所有工作区中当前所封锁的文件或记录。
 例如:

set exclusive off

use bk

repl num with num-3

for HH="CA1333" .AND. DAT="10/01/93"

Record is not locked

? RLOCK ( )

.T.

repl num with num-3

for HH="CA1333" .AND. DAT="10/01/93"

1 record replaced

unlock

● 网络函数

‥ 文件封锁函数flock ( )

格式: FLOCK ( )

flock( )函数用于对当前工作区共享打开的数据库文件的封锁。其封锁过程是: 首
先测试该文件是否已被其他用户封锁, 如果没有, 则对该文件封锁, 并且返回逻辑
真值.T.; 若其他用户已对该文件封锁, 则封锁不成功, 返回逻辑假值.F.。

一个用文件封锁函数flock( )设置封锁的文件, 可以通过unlock命令解锁, 关闭文
件或退出Foxbase系统也可以排除文件上的封锁。在设置封锁的文件上, 其他用户
不能再对它设置封锁。

‥ 记录封锁函数 Rlock ( )

格式: RLOCK ( ) 或 LOCK ( )

记录封锁函数RLOCK ( ) (或lock( ))对当前工作区中共享打开的数据库文件的当
前记录(记录指针所指的那条记录)设置封锁。其封锁的过程是: 首先测试该记录是
否已被其他用户封锁, 如果没有, 则封锁成功, 并返回逻辑真值 .T.; 若已被其他
用户封锁了, 则封锁不成功, 并返回逻辑假值 .F.。

封锁文件和封锁记录的目的, 都是为了防止多个用户同时操作数据库可能带来的数
据不一致性。但这毕竟是两级不同的封锁。它们在范围与特征方面是不同的:其一
是封锁的范围不同。flock()函数是对整个文件的封锁, 而RLOCK()(或lock()) 函
数仅对当前的一条记录封锁。其二是文件封锁后, 其他用户仍可用LIST命令查看,
而记录封锁后, 其他用户是不能查看的。

在FoxPro系统中, 有些命令有着特殊要求。

例如, insert [blank]、modify command、pack 、REINDEX、ZAP命令要求数据库
文件必须以排它方式打开。如果使用上述命令时, 文件又不是以排它方式打开的,
 则系统进入出错状态, 并显示下列信息:

Exclusive open of file is required

另外, 有些命令还具有自动封锁的功能。这些命令是:

append join

append froom recall <范围>

browse replace <范围>

delete <范围> update

index

如果文件不是以排它方式打开, 又没有对文件进行封锁, 执行上述命令时, 自动地
对文件进行封锁。否则, 则进入出错状态。

‥ error( )函数与message( )函数

在多用户环境下, 往往企图打开一个其他用户业已以排它方式打开的文件会导致错
误, 使用error( )函数, 在ON ERROR语言激活的情况下, 函数error( ) 就能捕捉
到错误号, 进行处理就可以排除因这类错误而使程序中止执行。

message( )函数同error( )函数一样, 能及时返回出错信息的字符串, 供用户程序
作相应处理。

‥ sys( )函数

格式: SYS (<数字型表达式>)

sys( )函数根据<数字型表达式>的值返回一个相应的字符串, 告之系统的有关信息
.

例如:

sys ( 0): 返回机器名字和网络机器号码

sys ( 5): 返回当前默认的设备

sys ( 12): 返回内存可用的剩余字节数

sys ( 9): 返回FoxPro序列号

sys ( 17): 返回所使用的处理器(8086/88, 80286或80386)

sys (102): 返回print的状态 (ON/OFF)


● 并发控制

为了保证数据库数据的正确性、完整性, 必须采取必要的保护措施。

‥ 数据的保护

在多用户环境下, 多个用户同时操作同一数据, 往往会带来数据的不一致性。为了
保证数据的正确性, 必须有相应的保护机制。上一节我们已介绍了文件打开的特征
, 它是数据保护的有效措施。另外, 也可以在循环语句中使用封锁函数来控制程序
的流程:

set exclusive off

use D1

time=0

do while .not. flock( )

if time<=1000

time=time+1

else

exit

endif

enddo

同样, 也可以用封锁函数对记录加锁。下面是相应的命令:

set exclusive off

use D2

go 8

do while .not. RLOCK ( )

? RLOCK ( )

enddo

‥ 死锁处理

在网络数据库设计与应用中, 常常会出现多个用户要排它性打开同一数据库文件或
在共享打开的文件, 两个以上的用户同时要封锁同一个记录的情况。 第一用户封
锁文件或记录后其他用户处理不断测试、判断和等待之中。 在同时处于等待状态
的两个或多个事务中, 其中的每一个在它能够进行之前, 都等待着某个记录, 而这
个数据已被它们中的某个事务所封锁, 这种状态称为死锁(deadlock)。

例如, 用户A和用户B的程序同时执行:

用户A程序 用户B程序

on error do err1 on error do err2

set exclusive on set exclusive on

select 1 select 1

use D1 use D2

┇ ┇

select 2 select 2

use D2 use D1

┇ ┇

从上述程序的执行可知, 用户A企图打开文件D2, 但D2已被用户B封锁了, 程序处于
等待之中, 等待用户B释放文件D2。同样, 用户B企图打开文件D1, 但D1已被用户A
封锁了,等待用户A释放D1。

在上述程序中, err1和err2是两个相同的出错处理程序:

if error ( )=108

retry

else

return master

endif

出错号108是表明文件无法打开. 用户A和用户B的程序均处于反复循环之中. 谁也
不释放自己封锁的文件,谁也无法打开想要打开的文件, 这样反复无休止地循环下
去。这种死锁现象是多用户环境下经常碰到的问题。我们必须能准确判断死锁, 提
供一套解决死锁的办法。

为了解决死锁问题, 首先必须弄清出现死锁的原因。一般来说, 在数据库中形成死
锁的主要原因有:

① 用户程序对数据资源的封锁是采取排它方式的。

② 已对某些数据资源设置了封锁的程序, 在执行过程中又继续请求对新的数据资
源封锁, 而不释放原已封锁的资源。

③ 对于封锁了数据资源但尚在处理中的程序, 不能将其挂起, 将它封锁的数据资
源临时授予其他程序使用。

④ 允许程序等待其它用户程序对数据资源的释放。程序间对数据的封锁请求形成
了相互等待状态。

针对上述产生死锁的主要原因, 进行预防性措施可以有效防止死锁问题。 一旦出
现了死锁现象, 也配有一套检测和解锁的方法。下面介绍两种常用方法: 一次封锁
法和顺序封锁法。

一次封锁法主要是为了避免相互封锁、相互等待的情况。它要求每个程序在执行前
, 必须对其使用的所有数据资源都进行封锁, 否则释放已封锁的部分资源。

在FoxPro中, 一个用户可以同时打开10个文件工作区。下面是利用一次封锁法封锁
m(m<=10)个文件的程序:

set exclusive off

do while .T.

select 1

use D1

if .not. flock( )

loop

endif

select 2

use D2

if .not. flock( )

close all

loop

endif



select m

use Dm

if flock( )

exit

endif

close all

enddo

上面的程序表明; 所谓一次封锁并不是用一条命令对这些文件加以封锁, 而是逐个
地依次加以封锁, 并且一次封锁成功。其中, 只要有一个文件封锁不成功,表示一
次封锁失败, 必须重新开始封锁。在重新开始封锁之前, 必须释放所有已经封锁成
功的文件。

对于一次封锁法的实现也可以用排它性打开文件来实现。下面是用ON ERROR 语句
的主程序和排错处理子程序ERROR1. prg的程序清单:

on error do error1

set exclusive on

do while .T.

share=1

use D1

if share=0

loop

endif

use D2

if share=0

loop

endif



use Dm

if share=1

exit

endif

enddo

出错处理程序ERROR1.prg

do case

case error( )=108

close all

share=o

retu

case error( )=... ─┐

┇ │

case error( )=... │ 其它出错处理

┇ │

endcase ─┘

顺序封锁法的主要思路是对每个文件给一个顺序号, 它要求用户在对数据文件进行
封锁时, 按所编文件序号顺序进行。

假定我们对十个文件(工作区)给出了相应的文件序号。而用户程序1、程序2和程序
3要对部分文件进行封锁(如下图)

1 2 3 4 5 6 7 8 9 10

文件顺序号 ─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─>


程序 1 -──────-──>

程序 2 ─────>

程序 3 ─────────────>


图中假设程序1封锁到顺序号为5的文件, 它不可能再要求封锁顺序号小于5的文件
 ,因此程序1不可能发生等待程序2的现象。只可能出现程序2等待程序1的情况。同
理, 不可能出现程序3等待程序1和程序2的现象, 只可能发生程序1和程序2等待程
序3 的情况。这样, 程序间只可能发生单方面的等待, 不会出现互相等待的现象,
则死锁就避免了。

当然, 一次封锁法和顺序封锁法能够解决一定范围的死锁问题, 但都有一定的局限
性。要想解决所有死锁问题, 还必须在用户程序加强一些保护性措施。 不断捕获
错误信息, 提供相应的解决错误的方法, 这样才可以完全避免死锁问题。

--
     来 人
      Welcome to Sunrise!

             我总有一种想为你而死的冲动

                          因为我不知如何才能把你打动

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 211.162.127.74]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店