最近在做数据库项目,遇到并行修改的问题。数据库sql,数据集adoquery,
属性
cursorLocation:clUseClient
cursorType:ctStatic
LockType:ltBatchOptimistic
如果 A B 都在访问同一条记录,A修改后更新没问题,此时B再更新就会出现“无法为更新定位行......”的错误,这问题应该怎么解决?如果需要自己加锁,有多少种锁,怎么加锁和解锁?还有怎么判定某一条记录有没有上锁呢?
属性
cursorLocation:clUseClient
cursorType:ctStatic
LockType:ltBatchOptimistic
如果 A B 都在访问同一条记录,A修改后更新没问题,此时B再更新就会出现“无法为更新定位行......”的错误,这问题应该怎么解决?如果需要自己加锁,有多少种锁,怎么加锁和解锁?还有怎么判定某一条记录有没有上锁呢?
解决方案 »
- 关于cxgrid中添加checkbox
- 我通过Visual source safe 下载的delphi 程序为什么设置了断点还能运行断点以后的程序(确定断点肯定被执行)
- 用Delphi7写一个DBF数据库更新检测程序,请给改进意见,
- word替换标记字符串问题
- 如何取到ShowModal出来的对话框中的数据?
- 程序出错什么原因?急!!
- 我就这几分了,帮帮忙吧:DBGRID的DBGrid的DblClick事件里,怎么判断双击了那个字段
- delphi中有没有能够从函数定义到函数声明的跳转?
- 怎么截获系统刷新桌面的消息?
- 要显示两个表的记录是否要用到两个Query控件和两个dbgrid控件?他们应该如何设置
- keeley20 来接分!
- mysterx 来接分
快肯定的sql快,关键是sql需要自己组织,批量是ado自动帮你组织成(其实也是通过sql)
更改前:
单据号 商品编码 数量
100 aa 10
100 bb 20
100 cc 30
……
更改后:
单据号 商品编码 数量
100 aa 15
100 bb 31
100 cc 28
……
就只能每一行用一条set...where...语句,有100行就循环100次,相当繁琐。还有,能保证query读和sql更新之间的时间段,记录不被别人修改,甚至不被别人找到吗?例如有一条记录
单据号 付款余额
100 123元
付款余额不能小于0(但数据库没有定义约束)A人query读:付款余额=123;
B人query读:付款余额=123;
B人sql:付款余额:=付款余额(123)-60;
执行
A人sql:付款余额:=付款余额(63)-70;
执行
(付款余额<0错误)
或者
A人query读:付款余额=123;
B人query读:付款余额=123;
B人sql:temp:=付款余额(123)-60;
付款余额(63):=temp;
执行
A人sql:temp:=付款余额(123)-70;
付款余额(53):=temp;
执行
(覆盖更新错误)sql能执行相应的语句,但结果都不是想要的结果。
你说的问题好像是类似 脏数据 的问题
这种情况,应该通过一个锁定/互斥的机制来保证,无论sql更新还是ado更新,都是需要的
比如oracle数据库在操作的时候就提供了行锁定或者表锁定的选择,ado本身只是向数据库提交一个操作请求,如果担心这个问题的话可以用存储过程来实现数据的操作另外你可以试着用ado的事务处理,当出现冲突执行失败的时候让事务回滚,并给个提示,让操作人员重新操作一遍.
ROWLOCK可以让你锁定一行,别的处理过程还可以读取表的其他行。
where 单号='2'第二条sqlselect * from 进货运行时先开第一个,再开第二个。看看问题出在哪?
这样的话,你最好用表锁吧。如果你觉得不放心,那么在你的应用程序中做处理(你的意思就是有一个处理过程在读取数据之后别的过程不能读取的),用mutex就可以,反正都是同一时刻是有一个过程在处理数据库。另:如果你有很多的客户端在读取、处理数据,最好用表锁,因为你的客户端不可能都在同一台机器上运行,所以,锁只能在服务器侧做。
呃……不好意思,没看完,现在明白你的意思了。
用READPAST可以跳过已经锁定的行。
互斥机制要怎么做?加一个bit类型的标识列吗?
普通打开,都是select的结果,
如果用户想修改,按一个按钮,进入修改,此时,其它人无法再浏览,
如果已经有其它人在浏览或修改,则本次“进入修改”失败,
修改完毕,保存后退出“修改”,
程序崩溃或断网,长时间后自动退出“修改”,此时程序(本崩溃而是断网后恢复)想保存,也无法保存了表+记录id+修改状态,专门通过一个表来维护