继续我最近关于操作SDE海量数据库的心得。我开发的一个功能是将MDB中的要素写入SDE要素类中,这个功能并不复杂,我早就写过一个非常 完备的LoadFeatureClass函数,但在加载要素之前,我还需要在SDE库中进行一些操作,也就是对每遍历一个MDB中的要素类时,必须对 SDE库中对应的两个要素类进行一些处理,结果,就非常“幸运”地频繁遇到了Network I/O Error[xxx(某个要素类)]。
根 据异常的提示,似乎SDE与Oracle之间发生了“不愉快”的事情,即链接断了,但这个可能性马上被我否定了,要知道我在初步测试用的是本机,不可能发 生这种情况。那第二个原因就是gsrvr.exe这个进程爆掉了,导致出现了这种异常假象,果然不出我的预测,在每次出现这个异常后,Oracle的会话 中只有一个SDE会话(如果连接上SDE,标准应该有两个SDE会话,一个是SDE监听会话,另一个是链接会话)。
gsrvr.exe这个链接进程为什么会爆掉?我在网上看了一些相关的文档,列举了七七八八的解决之道:
- 将Oracle9升级到9.2.0.3.0之后的版本【我升级到了9.2.0.7.0,没解决】
- 将Oracle9升级到Oracle10g【问题依旧】
- 给SDE91打上SP2补丁,sde91-genpatch3-ora9i-win补丁等【无效】
- 将Oracle的SPA/GPA调大【无效】
- dbinit.sde添加:“set DISABLE_SPATIAL_CACHE=TRUE”【依然无效】
会不会是我的代码问题呢?经过反复检查,这个因素被排除了,因为有几个相对数据量较小的MDB导入一切顺利,没有发生任何问题。
删除MDB中几个要素类看看?果然,在删除了4个要素类后,频繁出现的Network I/O Error问题居然消失了。
综 合前面发生的许多异常和这个问题,我最后得出了一个推论:一个SDE进程gsrvr.exe一次只能在SDE库中产生有限个数的要素游标,并且在每个游标 上能够传输的数据是有限的,否则gsrvr.exe就会爆掉。这两个因素是同时存在的,因为一个gsrvr.exe遍历SDE多个要素类不会产生问题,只 产生一个要素游标却传输上百万条数据也不会产生问题。
有鉴于此,最后的解决方法仍然是遍历了14-18个要素类后就强制关闭SDE链接,然后再产生SDE链接继续操作。虽然牺牲了时间,但却取得了可靠性。