Access编程交流网
  • 设为首页|收藏本站|繁体中文|手机版
  •     
  • Access培训-Access开发平台-Access行业开发

  • 首页
  • 资讯
  • 技巧
  • 源码
  • 行业
  • 资源
  • 活动
  • 关于

技巧

ACCESS数据库

启动/设置/选项/背景

修复/压缩

安全/加密/解密

快捷键

版本升级/其它等

数据表

命名方式/设计规范

表设计

查询

Sql语言基础

选择查询

更新查询

删除查询

追加查询

生成表查询

交叉表查询

SQL特定查询

查询参数

查询综合应用

界面/窗体/控件

标签

文本框

命令按钮

组合框/列表框

选项组/复选框/选项按钮

选项卡

子窗体

窗体本身/综合应用

其它

报表打印

报表设计

高级报表

模块/函数/VBA/API/系统

VBA基础

内置函数

调试/跟踪/Debug

模块/类模块

API/COM/系统相关

字符数字日期

网络通信游戏

加密解密安全

文件处理

经典算法

宏/菜单/工具栏/功能区

宏/脚本

菜单/工具栏

功能区/Ribbon

图表/图形/图像/多媒体

图表

图形/图像

音频

视频/动画

DAO/链接表/ADO/ADP

DAO/链接表/ODBC

ADO/RDO

ADP

ActiveX/第三方控件/插件

Treeview树控件

ListView列表控件

Toolbar工具栏控件

微软其它控件

Dbi-Tech

CodeJock

Grid++Report

FastReport

ComponentOne

加载项/插件/Addin

OFFICE集成/导入导出/交互

Excel导入导出/交互

Word导入导出/交互

PPT交互

Outlook控制/邮件

Text文本文件/INI/CSV

PDF/SWF/XML格式

CAD格式

Sharepoint/其它Office

SqlServer/其它数据库

表

视图

存储过程/触发器

函数

用户/权限/安全

调试/维护

SqlServer其它/综合

发布/打包/文档/帮助

开发版/运行时

打包/发布/部署

开发文档/帮助制作

Access完整行业系统

采购管理系统

销售管理系统

仓库管理系统

人力资源管理HRM

CRM管理系统

MRP/ERP管理系统

BRP/流程优化

其它管理系统

心得/经验/绝招
其它/杂项
Excel技巧

Excel应用与操作

Excel开发编程

Word技巧

Word应用与操作

Word开发编程

Outlook技巧

Outlook应用与操作

Outlook开发编程

热门文章

  • 在打开Ado记录集之前尽量..
  • SQL SERVER与AC..
  • ADO三大对象的属性、方法..
  • VB+ADO检测数据库并发..
  • 注意时间格式在sql se..
  • 如何在ADP中读取SQL服..

最新文章

  • 实验报告 --DAO与AD..
  • 用代码创建mdb格式的Ac..
  • 连接后台数据库提示 无法启..
  • 64位windows系统如..
  • Access的DAO准确获..
  • 利用代码自动创建ODBC源

联系方式

Access交流网(免费Access交流)

QQ:18449932 

网  址:www.access-cn.com

当前位置:首页 > 技巧 > DAO/链接表/ADO/ADP
DAO/链接表/ADO/ADP

VB+ADO检测数据库并发操作和处理并解决并发冲突

前言:

数据库并发问题详述http://www.csdn.net/Develop/read_article.asp?id=24366已经说明了并发的严重性与危害性。下面讲述VB+ADO来处理并发操作的实际案例:

在以前DAO中可以对数据库进行记录锁,页面锁,表锁来处理并发操作,还可以使用事务处理,那么现在怎么用ADO来检测并处理数据库的并发操作呢?

相关背景知识:

ADO中对数据库的也是采用锁定的方法来实现的,还可以用事务来做。事务有个特点就是:要么全成功,要么就全失败。那么在实际工作中有可能只有几条或一小部分的记录有冲突,只要对那一小部分的记录进行处理就行了。ADO也使用来锁定来实现。

那么什么是锁定?

锁定是一种进程,DBMS 通过该进程限制多用户环境中对行的访问。当一行或一列被独占锁定时,不允许其他用户在释放锁定之前访问锁定的数据。这确保了两个用户无法同时更新一行中的同一列。

从资源角度而言,锁定的成本可能非常高昂,只有在需要保持数据完整性的情况下才应当使用此功能。在每秒有数百或数千用户试图访问某个记录的数据库(例如连接到 Internet 的数据库)中,不必要的锁定将很快导致应用程序性能的下降。

可选择适当的锁定选项来控制数据源和 ADO 游标库管理并发性的方式。

打开 Recordset 之前先设置 LockType 属性,以指定提供者打开它时使用的锁定类型。读取该属性以返回打开的 Recordset 对象中使用的锁定类型。

提供者可能不支持所有锁定类型。如果提供者不支持请求的 LockType 设置,则替换为另一种锁定类型。若要确定 Recordset 对象中实际可用的锁定功能,将soppurts 方法与 adUpdate 和 adUpdateBatch 一起使用。

如果 CursorLocation  属性设置为 adUseClient,则不支持 adLockPessimistic 设置。如果设置了不支持的值,将不产生错误,而使用所支持的最相近的 LockType。

LockType 属性在 Recordset 关闭时为读/写,而在 Recordset 打开时为只读。

锁定类型种类(LockType 属性):
1.adLockBatchOptimistic
指示开放式批更新。需要批更新模式。

许多应用程序都一次提取多行,然后需要进行相应的更新,这些更新包括所有需要插入、更新或删除的行的完整集合。使用批游标只需一次往返服务器,因而导致更新性能的提高和网络通信量的降低。使用批游标库可创建静态游标,然后断开到数据源的连接。这时就可以对行进行更改,然后重新连接到数据源并将更改以批的形式发布到数据源。

2.adLockOptimistic
提供者使用开放式锁定,仅在调用 Update 方法时锁定记录。这意味着另一个用户有可能会利用您编辑记录和调用 Update 的时间间隔更改数据,这就会引起冲突。而使用此锁定类型时发生冲突的几率很低,即使发生了冲突也会很快得到解决。

3.adLockPessimistic
指示逐个记录保守式锁定。提供者要确保记录编辑成功,通常在编辑之前立即在数据源锁定记录。当然,这意味着一旦您开始编辑记录,这些记录就会对其他用户不可用,知道您通过调用 Update 释放锁定。如果您的系统不提供对数据的并发更改,例如预定系统,那么可使用此锁定类型。

4.adLockReadOnly
指示只读记录。无法改变数据。只读锁定是速度“最快”的锁定类型,因为它不要求服务器保持对记录的锁定。冲突

5.adLockUnspecified
未指定锁定类型。

检测和解决冲突:
如果在立即模式中处理 Recordset,则很少出现并发问题。另一方面,如果应用程序使用批模式更新,则在保存由一个正在编辑记录的用户所作的更改之前,编辑同一个记录的另一个用户比较有可能会更改记录。在这种情况下,需要应用程序准确处理冲突。无论是哪种情况,都可以使用 ADO 提供的 Field 对象的 UnderlyingValue 和 OriginalValue 属性来处理这些类型的冲突。将这些属性与 Recordset 的 Resync 方法和 Filter 属性配合使用。

检测错误
在批更新期间 ADO 遇到冲突时,将在 Errors 集合中放入警告。因此,调用 BatchUpdate 之后,一定要立即检查是否有错误,如果找到了错误,则应当假设已遇到冲突并开始进行测试。第一步要将 Recordset 的 Filter 属性设置为等于 adFilterConflictingRecords。该设置将使 Recordset对象限制为只显示那些发生冲突的记录。如果这一步之后 RecordCount 属性等于零,就说明错误是由冲突以外的其他原因引起的。

调用 BatchUpdate 时,ADO 和提供者将生成对数据源执行更新的 SQL 语句。下一步,调用 Recordset 的 Resync 方法,并且将 AffectRecords 参数设置为等于 adAffectGroup,将 ResyncValues 参数设置为等于 adResyncUnderlyingValues。Resync 方法将用来自基本数据库中的数据刷新在当前 Recordset 对象中的数据。通过使用 adAffectGroup,可以确保只有使用当前筛选设置的情况下可见的记录(即只有冲突记录)会与数据库重新同步。如果处理的是大型 Recordset,该操作会对性能有较大影响。通过在调用 Resync 时将 ResyncValues 参数设置为 adResyncUnderlyingValues,可以确保 UnderlyingValue 属性将包含数据库中的(冲突)值,并确保 Value 属性仍然是由用户输入的值,还会确保 OriginalValue 属性将持有字段的原始值(即在上一次成功进行 UpdateBatch 调用之前该字段所拥有的值)。然后,可以使用这些值通过编程方式解决冲突,或要求用户选择将要使用的值。

范例:

在调用 UpdateBatch 之前,本范例通过使用单独的 Recordset 来更改基本表中的值,人为地创建一个冲突。

'Begin
    On Error GoTo ErrHandler:   
    Dim objRs1 As New ADODB.Recordset
    Dim objRs2 As New ADODB.Recordset
    Dim strSQL As String
    Dim strMsg As String   
    strSQL = "SELECT * FROM Shippers WHERE ShipperID = 2"’SQL查询
    objRs1.CursorLocation = adUseClient’设置客户端游标
    objRs1.Open strSQL, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText’执行查询生成objrs1记录集
    objRs1("Phone") = "(111) 555-1111"’更改表中一条记录phone字段的值
    objRs2.Open strSQL, strConn, adOpenKeyset, adLockOptimistic, adCmdText’执行查询生成objrs2记录集
    objRs2("Phone") = "(999) 555-9999" ’更改表中记录phone字段的值
    objRs2.Update
    objRs2.Close
    Set objRs2 = Nothing   
    On Error Resume Next
    objRs1.UpdateBatch   
    If objRs1.ActiveConnection.Errors.Count <> 0 Then
        Dim intConflicts As Integer
        intConflicts = 0
        objRs1.Filter = adFilterConflictingRecords
        intConflicts = objRs1.RecordCount
        objRs1.Resync adAffectGroup, adResyncUnderlyingValues
        If intConflicts > 0 Then
           strMsg = "A conflict occurred with updates for " & intConflicts & "records." & vbCrLf & "The values will be restored"                     " to their original values."
           objRs1.MoveFirst
           While Not objRs1.EOF
                strMsg = strMsg & "SHIPPER = " & objRs1("CompanyName") & vbCrLf
                strMsg = strMsg & "Value = " & objRs1("Phone").Value & vbCrLf
                strMsg = strMsg & "UnderlyingValue = " & _
                                   objRs1("Phone").UnderlyingValue & vbCrLf
                strMsg = strMsg & "OriginalValue = " & _
                                   objRs1("Phone").OriginalValue & vbCrLf
                strMsg = strMsg & vbCrLf & "Original value has been restored."
                MsgBox strMsg, vbOKOnly, _
                      "Conflict " & objRs1.AbsolutePosition & _
                      " of " & intConflicts                 
                objRs1("Phone").Value = objRs1("Phone").OriginalValue
                objRs1.MoveNext
            Wend
            objRs1.UpdateBatch adAffectGroup
        Else
            strMsg = "Errors occurred during the update. " & _
                        objRs1.ActiveConnection.Errors(0).Number & " " & _
                        objRs1.ActiveConnection.Errors(0).Description
        End If
        On Error GoTo 0
    End If
    objRs1.MoveFirst
    objRs1.Close
    Set objRs1 = Nothing
Exit Sub
ErrHandler:
    If Not objRs1 Is Nothing Then
        If objRs1.State = adStateOpen Then objRs1.Close
        Set objRs1 = Nothing
    End If
    If Not objRs2 Is Nothing Then
        If objRs2.State = adStateOpen Then objRs2.Close
        Set objRs2 = Nothing
    End If   
    If Err <> 0 Then
        MsgBox Err.Source & "-->" & Err.Description, , "Error"
End If
'End
还可以使用当前 Record 的或特定 Field 的 Status 属性来确定已发生的冲突种类。

至此发生冲突的记录检查出来了,那么下一步就是处理失败的更新。

如何解决错误将取决于错误的性质和严重性以及应用程序的逻辑。实际中的数据库大都数是多个用户共享,典型的错误是其他人在你修改某个字段之前先修改了该字段。这种类型的错误称为“冲突”。ADO 将检测这种情况并报告错误。

如果存在更新错误,将被错误处理例程捕获。通过使用 adFilterConflictingRecords 常量来筛选 Recordset,可以只显示发生冲突行。

范例:

本错误解决方案将打印发生冲突的记录中的作者的名和姓(au_fname 和 au_lname)。

'Begin:

objRs.Filter = adFilterConflictingRecords

objRs.MoveFirst
Do While Not objRst.EOF
   Debug.Print "Conflict: Name =  "; objRs!au_fname; " "; objRs!au_lname
   objRs.MoveNext
Loop
'END

如果上述情况用事务来处理的话,那么对于用户数量较大网络较繁忙且更新记录数很多的情况来说将严重影响速度。上述方法只要处理发生错误的记录,这样就减轻了网络传输的负荷,有利提高速度。

作者Blog:http://blog.csdn.net/chenyu5188/
发布人:chenyu51…-chenyu5188 的 Blog  
分享到:
点击次数:  更新时间:2005-02-06 12:22:20  【打印此页】  【关闭】
上一条:API中VB字符串作参数传递的本质论  下一条:数据库并发问题详述



相关文章

  • • 实验报告 --DAO与ADO效率之比较
  • • 用代码创建mdb格式的Access文件
  • • 连接后台数据库提示 无法启动应用程序。工作组信息文件丢失,或是已被其它用户以独占方式打开 的解决办法
  • • 64位windows系统如何使用64位的ADO连接Accesss accdb数据库(ACE.OLEDB)
  • • Access的DAO准确获取记录集Recordset的记录数Recordcount
  • • 利用代码自动创建ODBC源
  • • 在打开Ado记录集之前尽量先判断记录集有否打开,如打开则先关闭之
  • • 快速获取Excel文件所有工作表表名

热门文章

  • [2003-12-21] ADO编程隐藏表access数据库
  • [2005-02-18] SQL语句集锦5access数据库
  • [2005-02-04] 使用代码刷新ODBC链接表access数据库
  • [2004-01-04] Access使用代码刷新链接表access数据库
  • [2006-11-20] 全面优化ADOaccess数据库
  • [2004-11-23] 在ADP中调用有参数存储过程最简单的方法access数据库

热门产品

公司动态|在线留言|在线反馈|友情链接|会员中心|站内搜索|网站地图

中山市天鸣科技发展有限公司 版权所有 1999-2023 粤ICP备10043721号

QQ:18449932

Access应用 Access培训 Access开发 Access平台

access|数据库|access下载|access教程|access视频|access软件

Powered by MetInfo 5.3.12 ©2008-2025  www.metinfo.cn