ADO 中 adLockPessimistic(悲观锁定)下面的陷阱


[作者注:已经转贴到:http://www.cnblogs.com/begincsdn/archive/2005/07/14/192501.html]
strSQLt = "SELECT * FROM MaxID WHERE cType='10A';"
rsSystem.Open strSQLt, cnSystem, adOpenDynamic, adLockPessimistic
With rsSystem
If Not .EOF Then
txtVouchID = !cFirstStr
lngID = !iCurrentID + 1
!iCurrentID = lngID
.Update
txtVouchID = txtVouchID & Format(lngID, "00000000")
Else
GoTo ErrorHandler
End If
.Close
End With
上面这段代码是一个企业内部应用的代码中的一段,且不论这段代码倒底结构或功能如何,我们关注点是在rsSystem.Open上。
这段代码的功能是生成指定类型单据的单据号,因为是顺序增量产生的,所以代码中
使用lngID=!iCurrentID+1,以期达到该值加1的目的,并且不允许同时有两次同号生成。
但这段代码在实际应用中总是出现问题,即总有重复的单号产生,对于我,并不熟悉VB,但仔细阅读这段代码后。觉得这段代码
有点像操作系统临界区的味道。

仔细看:如果两个人同时进入Open阶段,如果按悲观锁定,是不是只有一个人能打开呢?

我们知道,在ADO的RecordSet打开时,有四种锁方式:
adLockReadOnly 预设值。唯读 -- 您无法变更资料。
adLockPessimistic 悲观性锁定,通常会在编辑时立即在资料来源锁定记录。
adLockOptimistic 乐观性锁定,在您呼叫 Update 方法时才锁定。
adLockBatchOptimistic 悲观性批次更新。

根据上面的提示,还不能完全确定这段代码是不是有问题。
事实上是有问题的,因为adLockPessimistic只对Update才锁定,对于Select本身并无效,
在第一个操作者Update之前,第二个Select操作成功并获取了当前的MaxID后,结果就麻烦了。
第一个人Update成功,第二也因为取得了上一次操作者所取得的最大值而操作成功。
两张同单号单据产生了。

解决办法:
使用Update语句在前。语句改写成:
strSQLt = "Update MaxID set iCurrentID=iCurrentID+1 where cType='10A';SELECT * FROM MaxID WHERE cType='10A';"
后面不再在程序内作计算即可以解决该问题啦。



优质内容筛选与推荐>>
1、dev 中的GridControl中的行实现选择的功能实现
2、从优先级排序看敏捷开发的自相似性
3、SharePoint 2010 SP1
4、根据不同时间段返加不同结果,
5、湖南省第6届程序大赛第二题 弟弟的作业


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号