实际业务中碰到了PB开发的业务系统造成的数据死锁情况,整理了一些PB关于数据库死锁的一些处理。
PB死锁相关
1. 即时的commit和rollback
不同数据库的锁机制各不相同,但对应用程序来说,造成死锁的最大可能就是:没有养成对每个 COMMIT 的执行结果进行检查的编码习惯,导致提交出错时未能及时 ROLLBACK 造成死锁。
示例代码:
sqlca.autocommit=false //一定要设置为不自动提交
string ls_err
dec ldec_xxx
select column_xxx into :ldec_xxx from TABLE_yyy where id=keyvalue; //如果有必要查询当前值的话.
if sqlca.sqlcode <0 then
ls_err=sqlca.sqlerrtext //先读错误信息,然后立即ROLLBACK再提示,以免提示时用户不确定,表还在锁定中
rollback; //立即回滚,以免其它用户等待.
messagebox("提示","数据库发生以下错误:~n"+ls_err)
return
end if
commit using sqlca;
2. sqlca.autocommit(参考)
在使用有增、删、改的语句时在前边加锁、更改完毕后解锁即可:
sqlca.autocommit=true
insert.......
update .......
delete......等语句
sqlca.autocommit=false
3. 用DataWindow操作的话:
1)Dw的Specify Update Characteristics属性:
设置DW的Specify Update Characteristics为: (3)Key and Modified Columns
这样,只要你更新的列的值没有变,则大家都可以成功,有效的防止了多用户重叠更新的问题,相当安全,不必使用第二选项.
2)数据窗口的RetrieveEnd事件
在数据窗口的Retrieveend事件的脚本中加COMMIT USING SQLCA;
呵呵,PB是有这个问题,以前给别个说的时候有些人还不信。你可以在数据窗口的RetrieveEnd事件里面加上一句“commit;”就OK了。个人认为是数据窗口在检索出数据后仍然占据着相应的表资源,直到提交数据为止才会释放,也就是结束本次事务,开始新的事务。PB这样做可能是为了保证数据的完整性,使用我说的解决办法,经测试没有发现什么问题,但是也不能保证完全没问题,有问题的话也是出在数据库的并发控制上,有兴趣自己去测试一下嘛。
4. SQLCA.LOCK属性(RC或RU)
设置sqlca.lock='RU',这样的缺陷是降低了读取数据的安全级别。
示例代码:
// Profile iadserver
SQLCA.DBMS = "OLE DB"
SQLCA.LogPass =profilestring('dbms.ini' , "database" , "logpass" , "")
SQLCA.LogId = profilestring('dbms.ini', "database" , "logid" , "")
SQLCA.AutoCommit = False
SQLCA.Lock='RC'
SQLCA.DBParm = "PROVIDER='SQLOLEDB',"+&
"DATASOURCE='" + profilestring('dbms.ini' , "database" , "serverip" , "") + "'," +&
"PROVIDERSTRING='Database="+profilestring('dbms.ini' , "database" , "dbname" , "")+"'"
connect using sqlca ;
if SQLCA.SQLCode <> 0 then
messagebox("提示信息:", '连接数据库出错!' + SQLCA.SQLErrText , stopsign!)
rollback using sqlca ;
halt close
end if