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

Datomic中db.fn/cas的旧值是否允许使用查找引用?

关于Datomic db.fn/cas 使用查找引用作为旧值失败的问题

嘿,这个坑我之前踩过!你的判断方向是对的——Datomic的db.fn/cas操作不允许用查找引用(比如[:task-state/name "locked"]这种形式)作为v-old参数,哪怕你确认这个查找引用对应的实体确实存在也不行。

为什么会报错?

Datomic里引用类型的属性(比如你的:task/state),实际存储的是关联实体的实体ID(EID),而不是查找引用向量。当你执行CAS时,Datomic会直接把你传入的v-old和属性当前存储的值做精确比对:

  • 你传入的v-old是[:task-state/name "locked"](一个向量)
  • 但属性当前的实际值是报错里显示的17592186045558(一个数字EID)
    两者类型和内容都不匹配,自然就触发了:db.error/cas-failed错误。

怎么解决?

你需要先查询出旧状态对应的实体ID,再把这个ID作为v-old传入CAS操作:

  1. 先执行查询获取旧状态的EID:
    (def old-state-eid (d/q '[:find ?e . :where [?e :task-state/name "locked"]] your-db-connection))
    
  2. 然后用这个EID替换CAS里的查找引用:
    [[:db.fn/cas id :task/state old-state-eid [:task-state/name "pending"]]]
    
    (注:新值[:task-state/name "pending"]可以保留查找引用,Datomic会在事务中自动解析成对应的EID)

关键要点总结

  • db.fn/cas的v-old必须是属性当前存储的精确值:对于引用类型属性,就是关联实体的EID,不能用查找引用。
  • 新值v支持使用查找引用,Datomic会自动解析,但旧值不支持这种语法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:30:50