我将Clojure与JDBC结合使用,以便在响应事件时从两个不同的数据库(特别是MySQL和Vertica)中选择记录并将其插入两个数据库中。我希望所有这些操作都在一个事务中进行,如果任何一条命令出了问题,都可以将其回滚。
(defn handle-request
[request]
(jdbc/with-db-transaction [mysql-conn config/mysql-db-spec]
(jdbc/with-db-transaction [vertica-conn config/vertica-db-spec]
(let [record (query-some-data mysql-conn request)]
(update-some-data! mysql-conn record)
(insert-some-vertica-data! vertica-conn record)))))
我担心这会冒着Vertica交易成功的风险,而不是MySQL交易的风险。 Clojure处理该操作的最惯用方式是什么?
最佳答案
事务是数据库提供的行为,而不是您用于从数据库发送/检索数据的编程语言提供的行为。因此,答案是您无法进行“真实”交易,因为无法协调两个数据库。
(perform mysql tx)
if (successful) then
(do vertica tx)
(do tx in DB 1)
(try
(do tx is DB 2)
(catch Exception ex
(rollback tx in DB 1)))
但是,这不是最佳选择,因为您现在是自己编写一个本地数据库插件,而不是利用数据库的内置稳定性和可靠性(即如果catch子句完成运行之前出现问题怎么办?)。