VB数据库存取.docx
- 文档编号:25089536
- 上传时间:2023-06-05
- 格式:DOCX
- 页数:11
- 大小:22.64KB
VB数据库存取.docx
《VB数据库存取.docx》由会员分享,可在线阅读,更多相关《VB数据库存取.docx(11页珍藏版)》请在冰豆网上搜索。
VB数据库存取
VB数据库存取
多客户环境下VB数据库编程之
1.多客户环境下数据库的储存方式。
在客户/服务器系统中,应用程序一般分为两种情况:
一种是把整个应用程序放到网络服务器上,允许多个用户打开数据库。
在这种情况下,用户可以共享组成应用程序的所有数据库对象,包括存储数据的表。
另一种是把应用程序分为两个数据库(双数据库):
一个是包括应用程序数据表的后端数据库,另一个是包含应用程序其它对象(查询、窗体、报表、宏和模块)的前端数据库,前端数据库还可以管理临时对象。
后端数据库放到网络服务器上,而前端数据库分发给用户,使来自后端数据库的连接表作为前端数据库对象的基础。
在多用户环境中,双数据库方法具有较为明显的优势,因为应用程序不必建立可可能与另一个用户发生冲突的临时表。
因此,在用户工作站上存储前端数据库,可以避免对临时对象的争用;同时,由于在本地存储静态对象,因而当应用程序运行时,可以使网络通信量减少到最小。
2.静态部件与动态部件。
应用程序中的部件可以归为两类,即静态部件和动态部件。
(1)静态部件:
应用程序中相对稳定,即不经常改变的部分。
常用的静态部件是组成调用MicrosoftJet宿主程序的动态链接库(.dll)和可执行文件(.exe),例如VisualBasic,MicrosoftAccess,MicrosoftExcel等。
此外,应用程序中的部件,如窗体、报表和程序代码等,也属于静态部件。
静态部件不经常改变,因而是工作站存储的理想选择。
为了获得最佳性能,通常把静态对象安装在本地工作站上。
这种情况下,当应用程序的设计变更时,必须对本地工作站上的对象进行更新。
但是,如果用户工作站的磁盘空间不够用,或者希望能更好地控制静态部件的变更,则可以把静态部件存储在网络服务器上。
这样做会明显增加网络的通信量和降低应用程序的性能,但可以使应用程序更易于管理。
当然,如果可能的话,最好把静态部件存储在用户端。
把部件移到工作站上,将会给应用程序的管理带来一些麻烦。
例如,当需要修改应用程序的静态对象时,例如修改表的结构或程序代码,必须有相应的机制来更新每个工作站上所有受影响的部件。
当工作站较多时,这种操作相当费时费力。
为了解决个问题,可以使用下两种方法:
·在启动应用程序时检查部件的最新版本。
例如,应用程序的启动代码可以把本地数据库中静态对象的修改日期与服务器的中央数据库中的日期进行比较,如果发现服务器对象的日期较新,则自动输入对象的最新版本,使本地数据库保持最新。
·用MicrosoftJet的复制功能使对象同步。
例如,可以建立数据库的复本并把它们存储在工作站上,然后就可以通过复制功能自动使对象同步。
"数据库复本"在后面将讲到。
(2)动态部件:
是一些文件,由在多用户环境中用户访问的实际数据组成。
这些文件
包括MicrosoftJet数据库(.mdb)文件、外部数据库文件(如MicrosoftFoxPro数据库文件)或存储在数据库服务器上的ODBC数据库文件。
和静态部件一样,应用程序动态部件的存放位置同样可能是决定应用程序总体性能的主要因素。
例如,假定把应用程序的数据文件放置在网络服务器上,而且应用程序必须在没有索引的表中查找一个记录。
在这种情况下,MicrosoftJet必须对整个表进行顺序扫描以查找匹配结果,这意味着必须把整个表从服务器传送到引擎的工作站。
当表很大时,这种操作可能需要较长的时间。
同时,由于用户在执行查找时长时间地等待响应,而网络上大量的通信还会轮流地降低其他用户的速度,所以这个问题会更加复杂。
为了缓解这种情况,可以给应用程序要查找的列添加索引。
但是,添加索引又可能会增加网络通信量,而且降低了并发和性能。
这就是说,通过网络访问文件显然比在本地计算机上访问文件慢,在多用户环境中实现数据库系统实际上是以牺牲系统性能为代价的。
因此,为了减小网络的通信量,最好将某些应用程序的部件存储在本地工作站上。
例如,假定应用程序使用一套存储邮政编码或零件编号表,而这些表不经常改变,则可以把它们移到本地工作站上,以避免网络访问。
3.MicrosoftJet多用户模型。
MicrosoftJet多用户数据库应用程序由几个重要部件构成。
在每个用户的工作站上都有MicrosoftJet的一个拷贝在运行,如果使用双数据库方法,则通常静态部件会驻留在每个用户的计算机上,而动态部件会驻留在网络服务器上。
除此之外,多用户应用程序具有下列文件:
一个工作组信息文件,它可以集中驻留在网络服务器上,也可以驻留在每个用户工作站上;每个数据库有一个锁定信息文件(.1db),它驻留在与数据库相同的文件夹内。
1).工作组信息文件
工作组信息文件是一个MicrosoftJet数据库,用来存储用户、组和密码信息以及用户设置的各种选项信息。
在多用户环境中,工作组信息文件的位置是很重要的。
可以把工作组信息文件放在每个本地工作站上,也可以把它放在网络服务器上。
如果把它存储在本地机上,则必须在变更安全性设置值时采取必要的步骤对它进行更新。
2).锁定信息文件
锁定信息文件(.1db)用来存储数据库中所有当前锁定记录的信息。
在打开数据库时,如果锁定信息文件不存在,则MicrosoftJet数据库引擎会自动建立该文件。
MicrosoftJet为每个以共享模式打开的MicrosoftJet数据库文件建立一个锁定信息文件。
该文件与打开的相应数据库同名,但文件名后缀为.1db。
例如,与Northwind.mdb相对应的锁定信息文件名叫Northwind.1db。
锁定信息文件与数据库存储在相伺的文件夹中。
在数据库关闭时,MicrosoftJet会删除.1db文件。
在多用户环境中,则在所有用户都退出应用程序时将其删除。
MicrosoftJet支持下列文件服务器和点对点网络:
.MicrosoftWindowsNT和Windows95网络
.BanyanVINES5.52
.DECnet4.1
.LANtastic5.0
.NovellNetWare3.x和4.x
.OS/2LANManager2.1和2.2
一般来说点对点网络不能很好的满足多用户数据库系统的要求,大多数应用程序要求运行在有专用的文件服务器的网络上。
在单用户环境中,只有一个用户在访问数据,因此应用程序不会发生资源请求冲突。
而在多用户环境中,当用户访问数据时,可能会发生冲突。
为了管理这些冲突,MicrosoftJet提供了数据访问控制和应用程序的锁定服务,以保证在给定的时间内只有一个用户可以访问数据。
数据访问控制用来对数据库的部分或全部进行访问限制,通常可分为两类,一类是用户限制,另一类是功能限制。
用户限制用来阻止某些人(或只允许某些人)查看或修改"敏感"数据。
例如,在工资系统中,大多数人可以查看职工的工资,但只有少数人才有权修改实际的工资信息。
功能限制只对程序的某个部分起作用,而不管用户是谁。
例如,在订单登记系统中,如果把价格表设为只读模式,则可防止用户随意修改某些项目的价格。
在应用程序中,可以通过程序控制或MicrosoftJet数据库引擎控制来处理限制。
其中程序控制可以施加于程序自身,而引擎级控制则限制了任何试图访问数据库信息的程序。
1.互斥地使用数据库。
以互斥方式打开数据库是对数据访问施加的最大限制,它实际上是以"独占"方式使用数据库。
这种限制可以阻止任何用户或程序访问正在使用的数据库中的信息。
由于这种方式的限制太大,因而只用于那些影响整个数据库的操作,包括:
·压缩数据库。
·更新整个表(例如用UPDATE查询)。
·通过添加表、字段或者索引来修改数据库的结构。
·处理特殊的用户需求(例如传送审计信息)。
在程序代码中,为了以独占方式打开一个数据库,必须把OpenDatabase方法的第二个参数设置为True,例如:
DimoldDbAsDatabaseDimoldwsAsworkSpaceSetoldDb=oldWs.OpenDatabase("Members.mdb",True,False)
用上面的代码打开数据库时,如果该数据库未被其它用户使用,则打开数据库,这样直到关闭之前,该数据库不会被其它用户或程序访问;如果数据库正在被其它用户使用,则返回一个错误。
2.拒绝其它用户或程序访问指定的表。
以独占方式打开数据库后,可以拒绝其它用户或程序访问整个数据库(包括数据库中的每个表)。
而对数据访问的一种较轻的限制则是拒绝其它用户或程序访问由本人程序正在使用的表(即记录集),它实际上是对记录集进行锁定。
锁定记录集的操作通过OpenRecordset方法中的Options参数来实现。
我们知道,OpenRecordset方法的格式如下:
对象.OpenRecordset(type,OPtlons,lockedits)
其中的options参数用来设置对记录集的锁定,该参数可以取多种值,以下两种值用来禁止其它用户对记录集进行读写操作:
1..禁止读(dbDenyRead)
OpenRecordset方法中的dbDenyRead常量用来禁止其它用户查看表中的数据,直到关闭该表为止。
当需要更新整个表中的信息时,可以使用这个常量。
例如:
DimrstasRecordsetSetrst=dbs.OpenRecordset(strTable,dbOpenTable,dbDenyRead)
2.禁止写(dbDenywrite)
OpenRecordset方法中的dbDenyWrite常量用来禁止其它用户更新表中的数据,直到关闭该表为止。
在这种情况下,其它用户可以查看表中的信息,也可以添加新记录,但不能对其进行修改。
当需要向表中插入新记录而又不想修改现有的记录时,可以使用这个常量,它对表和动态集都有效。
例如:
DimrstasRecordsetSetrst=dbs.OPenRecordset(strTable,dbOpenTable,dbDenyWrite)
用dbDenyRead和dbDenyWrite可以分别禁止对记录集进行读和写,如果既想禁止读,又想禁止写,则可同时使用这两个常量(用"十"号连接)。
例如:
DimrstasRecordsetSetrst=dbs.OpenRecordset(strTable,dbOpenTable,dbDenyRead+dbDenyWrite)
前一节介绍了对数据访问的一些限制,其中讲到了对表的锁定。
这一节将进一步地谈一谈如何实现共享数据的锁定操作。
要保护共享数据,可以在用户编辑数据时锁定它。
数据被锁定后,任何用户都可以读取它,但仅有一个用户可以修改它。
MicrosoftJet可以在以下三种不同的级别上锁定数据:
·独占模式:
阻止其他所有用户访问数据库,这是限制最
用记录集锁定可以锁定Recordset对象基本表,也可以指定只读或(和)只写访问。
记录集锁定只能应用于表类型和动态集类型的Recordset对象,页面锁定(见下一节)不能应用于快照类型和仅向前类型的Recordset对象,因为它们本来就是只读对象。
尽管如此,MicrosoftJet仍提供了共享表读锁定和共享表写锁定。
(1).打开记录集。
以共享模式打开数据库之后,可以通过在OpenRecordset方法的oPtions参数中指定不同的选项来实现记录集锁定。
为了用锁定打开一个记录集,可按如下步骤操作:
1.)以共享模式打开Recordset对象的数据库。
2.)用OpenRecordset方法打开记录集,并把Options参数设置为所需要的锁定方式。
3.)当Recordset对象的使用结束时,关闭该对象以释放所有记录集级的锁定。
编写一个Function过程,以独占方式打开一个表。
FunctionOpenTableExclusive(dbsAsDatabase,rstAsRecordset,strTableAsString)AsIntegerSetrst=dbs.OpenRecordset(strTable,dbOpenTable,dbDenyRead+dbDenyWrite)
SelectCaseErrCaSe0:
OpenTableExclusive=0CaSeElse:
OpenTableExclusive=-1EndSelectErr=0EndFunction
该过程通过dbDenyWrite和dbDenyRead选项常数的组合,以独占模式打开一个表。
如果过程调用成功(返回0),则在Recordset变量被显式或隐式地关闭之前,其它用户将不能访问该表。
如果其它用户已经以独占模式打开该表,或者发生了一个非预期的错误,则该过程返回-1。
为了调用上述过程,可以在窗体上画一个命令按钮,然后编写如下的事件过程:
PrivateSubCommand1_Click()
DimaAsIntegerDimMvDbsAsDatabaseDimMvTabsAsRecordsetSetMyDbs=OpenDatabase("C:
\dbdir\dbl.mdb,true)
a=OpenTableExclusive(MyDbs,MyTabs,"Tabel1")
SelectCasea
Case0:
MsgBox"调用成功"
CaseElse:
MsgBox"调用出错"
EndSelectEndSub
注意,如果打开一个Recordset对象时没有指定option:
参数值,则MicrosoftJet将使用页面锁定。
在这种情况下,将以共享模式打开记录集,并且不禁止其他用户访问记录集中的数据,但它确实锁定了当前页中正在编辑的数据。
(2).在打开记录集时检查错误。
和以独占模式打开数据库一样,当对Recordset对象设置锁定时,如果锁定失败,则会产生错误。
如果某个用户以禁止其它用户获得锁定的方式打开了一个Recordset对象,则当试图锁定该Recordset对象时将会发生最常见的错误,即3262,其出错信息为:
"不能锁定表XXX;当前正被用户XXX在机器XXX上使用。
"。
当试图对不能锁定的对象使用OpenRecordset方法时,也会产生这个错误。
从理想的角度来说,如果能对记录进行锁定,则会给多用户程序带来极大的灵活性。
然而遗憾的是,MicrosoftJet引擎不支持真正的记录锁定,而是使用页面锁定。
页面锁定只锁定包含当前正在编辑的记录的页,MicrosoftJet进行访问和锁定的页的大小为2K(2048个字节)。
在使用页面锁定时,其他用户可以读取锁定页中的数据,但不能对数据进行修改。
在这种锁定方案中,每次将锁定多个记录,锁定的记录的个数取决于每个记录的大小。
例如,如果每个记录的长度为230个字节,则每次只能锁定9个记录;而如果记录的长度为30个字节,则每次可锁定68个记录。
锁定模式。
页面锁定分为两种模式,即保守式锁定和开放式锁定,它确定了MicrosoftJet如何对数据进行锁定。
当编写在页面级别上锁定数据的应用程序时,必须确定要使用哪种锁定模式。
页面锁定可以通过两种方法来设置,即LockEdits属性和OpenRecordset方法中的lockedit5参数。
1.用LockEdits属性指定锁定模式。
锁定模式可以通过LockEdits属性来指定。
该属性可用于各种Recordset对象,包括动态集、快照、表及动态类型的Recordset对象。
LockEdits属性是一个布尔值,当把该值设置为True(缺省)时,将对记录集进行保守式锁定,即在执行Edit方法时锁定2K的页面:
如果把该属性设置为False,则对记录集进行开放式锁定,即在执行UPdate之前不锁定要更新的记录所在的2K页面。
如下面的例子:
DimrstTemPAsReCordset
…
rstTemp.LockEdits=True
说明:
a.锁定页面后,其它用户不能对正在编辑的记录所在页面进行修改,但可以读取锁定页中的数据。
在其它用户锁定页面后,如果再把LockEdits属性设置为True,则会出错。
b.如果把LockEdits属性设置为False,且其它用户已锁定页面,则其后的用户在使用Update时将会出错。
c.当与Microsoft连接的ODBC数据源一起操作时,LockEdits属性被设置为False,即开放式锁定。
2.用OpenRecordset方法指定锁定模式。
我们已多次使用过OpenRecordset方法,该方法的格式如下:
Setrecordset=object.OpenRecordset(type,options,lockedits)
其中第三个参数,即lockedits,用来指定锁定模式或以只读方式打开记录集。
该参数可以取以下5种值:
(1)dbReadOnly:
以只读方式打开记录集。
注意,在options参数中也可以使用dbReadOnly,但不能同时使用,否则会产生错误。
(2)dbPessimistic:
用保守式锁定模式打开记录集,一旦使用Edit方法,将立即锁定正在编辑的记录所在的页面,直到执行Update方法后才释放对该页面的锁定。
(3)dbOptimistic:
用保守式锁定模式打开记录集,在执行Update方法前不锁定正在编辑的记录所在的页面。
(4)dbOptimisticValue:
基于行值使用开放式并发(仅ODBCDirect工作区)。
(5)dbOptimisticBatch:
允许开放式更新(仅ODBCDirect工作区)。
保守式锁定和开放式锁定。
1).保守式锁定。
保守式锁定也称为悲观锁定。
设置保守式锁定后,只要对某个记录使用Edit方法,就自动锁定该记录所在的页面,直到显式地提交或取消这个记录的变更(例如执行UPdate方法)后,才释放对该页面的锁定,并把数据写入文件中。
保守式锁定是Recordset对象的缺省锁定方式。
保守式锁定的主要优点是,获得锁定之后,只要记录还被锁定着,就可以防止其它用户修改该记录中的数据,因此不会发生任何锁定冲突。
另外,由于一个用户不能在另一个用户开始编辑记录之后改变它,所以,保守式锁定也是保证应用程序读取最新数据的唯一方法。
保守式锁定的缺点是,在编辑和锁定该记录的过程中,包含该记录的整个页面都被锁定。
当锁定时间较长时,可能会给其它用户造成不必要的麻烦。
例如,用户设置保守式锁定后,开始编辑一个记录,并在记录被锁定期间离开了计算机(例如出去办事),这不仅锁定了用户正在编辑的记录,而且锁定驻留在该锁定页面内的其它记录,使其它用户长时间内无法编辑页面中的记录。
2).开放式锁定。
开放式锁定也称乐观锁定。
使用开放式锁定时,MicrosoftJet引擎仅在试图用Update方法提交记录变更时才锁定页面,完成更新操作后立即释放对页面的锁定。
由于锁定仅在应用程序试图提交变更时发生,因此能使锁定的时间最短,使其它用户只在锁定生效的较短时间内不能访问该页面。
这是开放式锁定的主要优点。
开放式锁定的缺点是:
当用户正在编辑记录时,不能保证更新是否会成功。
如果另一个用户改变了第一个用户正在编辑的记录,那么依赖于开放式锁定的更新将会失败。
例如,假定张三和李四正在编辑同一个记录,张三开始以开放式锁定编辑某个客户记录。
由于张三使用的是开放式锁定,并没有真正锁定记录,所以不能禁止李四试图编辑相同的记录。
在李四编辑相同的客户记录时,他不知道张三正在编辑该记录,并且也没有看到最新的数据。
当张三试图在李四编辑相同的客户记录时存储他的变更,就会产生一个错误。
对于大多数数据库应用程序来说,可能要选择开放式锁定,因为其它用户修改或删除本人正在使用的记录的可能性要小于试图访问已被锁定的页面上记录的可能性。
但是,如果某个应用程序中有多个用户同时访问和编辑记录,则应使用保守式锁定,以确保在执行编辑期间记录不被其他人修改。
在这种情况下,应注意不要使记录锁定的时间过长。
3).释放锁定。
如前所述,在执行Update方法后,将自动释放页面锁定。
但是,释放记录锁定是一种后台进程,有时候,其它操作发生得很快,以至于数据库来不及处理该进程。
如果正在开发一个数据输入密集型的应用程序,则可能需要暂停应用程序的处理,这可以通过MicrosoftJet数据库引擎的Idle方法来完成。
Idle方法挂起数据处理,启用MicrosoftJet数据库引擎执行其它操作,诸如内存优化或内存页超时等(仅MicrosoftJet工作区)。
该方法用于DBEngine对象,格式如下:
DBEngine.Idle[dbRefreshCachel
在多用户环境中,用Idle方法可以使MicrosoftJet数据库引擎执行后台任务。
在一般情况下,仅当没有任何操作(包括移动鼠标)发生时,才释放读锁定并更新本地动态集类型的Recordset对象中的数据。
如果定时地使用Idle方法,则MicrosoftJet可以释放不必要的读锁定,以捕获后台处理任务。
Idle方法有一个可选的参数,即dbRefreshCache,如果使用该参数,则可强制挂起写入.MDB文件,并用.MDB文件中的最新数据刷新内存。
实现页面锁定时使用开放式锁定,可按如下步骤操作:
(1)打开一个表类型或动态集类型的记录集,它就是想要编辑的数据。
(2)把数据指针移动到一个记录上。
(3)把记录集的LockEdits属性设置为False,指定开放式锁定。
(4)用Edit方法编辑该记录(该记录还没有被锁定)。
(5)提交该记录。
(6)用Update方法来提交记录的变更(这将试图锁定记录)。
(7)检查Update方法是否成功。
如果没有成功,则再试;
当使用事务时,开放式锁定将转换为保守式锁定。
因为在提交事务之前,事务一直拥有写锁定,所以即使把LockEdits属性设置为False,也会转换为保守式锁定。
在保守式锁定中,Update方法可能会失败。
这是因为Edit方法没有设置写锁定,并不意味着Update方法没有置写锁定。
换句话说,当一个用户用保守式锁定打开记录集时,即使第二个用户使用的是开放式锁定,他对相同数据的更新也会失败。
下面通过一个例子说明如何实现保守式锁定。
编写一个Function过程,用
特别声明:
1:
资料来源于互联网,版权归属原作者
2:
资料内容属于网络意见,与本账号立场无关
3:
如有侵权,请告知,立即删除。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VB 数据库 存取