You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Clojure读取Oracle几何数据为WKB字符串时遇连接关闭异常

解决 Clojure 读取 Oracle WKB 时的 Closed Connection 异常

这个问题我之前也碰到过,核心原因是 clojure.java.jdbc 默认会在查询完成后立即释放数据库连接,但你尝试读取BLOB流的操作是在连接关闭之后进行的,自然就会抛出连接关闭的异常了。

为什么会出错?

你的代码里,j/query执行完毕后,底层的数据库连接就被归还给连接池了。这时候再去调用.getBinaryStream()和.readAllBytes(),BLOB对象已经失去了连接上下文,所以报错。

两种简单的解决方案

方案1:让 JDBC 自动把 BLOB 转换成字节数组

clojure.java.jdbc 支持通过配置参数直接将BLOB类型映射为字节数组,这样查询结果里的:wkb直接就是你需要的字节数据,无需手动处理流:

(require '[clojure.java.jdbc :as j])

;; 直接在 query 中指定 :blob-type 选项
(->> (j/query db 
               "select SDO_UTIL.TO_WKBGEOMETRY(geometry) wkb from t where idf = 1"
               {:blob-type :bytes})
     (map :wkb))

方案2:在连接保持打开的状态下处理流

如果需要手动处理流(比如处理大BLOB),可以用j/with-db-connection来显式保持连接打开,直到你处理完所有结果:

(require '[clojure.java.jdbc :as j])

(j/with-db-connection [conn db]
  (->> (j/query conn "select SDO_UTIL.TO_WKBGEOMETRY(geometry) wkb from t where idf = 1")
       (map (fn [row]
              ;; 使用 with-open 确保流被正确关闭
              (with-open [blob-stream (:wkb row)]
                (.readAllBytes blob-stream))))))

小提示

推荐优先用方案1,因为它更简洁,也避免了手动管理流和连接的麻烦。如果是处理非常大的WKB数据,方案2可以让你更灵活地控制流的读取方式(比如分块读取)。

内容的提问来源于stack exchange,提问作者Bogdan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:39:18