Lookup refs used within a transaction are resolved against not the last state of DB

Hi, the next case was met by executing simultaneous transactions where one of transaction used lookup ref to resolve entity to be updated:

  1. Create entity e1 with unique attribute value [:User/name "User-1"]
  2. Retract entity e1
  3. Update e1 using lookup ref [:User/name "User-1"]
    Step 3 is expected to be failed with the error: Unable to resolve entity: [:User/name \"User_1\"] but we got the cases when the step 3 was executed successfully

In our case step 2 and step 3 was executed by two different peers and according to transaction history with time in difference 8 seconds between them.

To reproduce in repl within single peer the step 2 should be executed asynchronously

(require '[datomic.api :as d])
(def connInternal (d/connect "datomic:dev://localhost:4334/dbName?password=datomic"))

(def user-schema [
                   {
                       :db/ident :User/name
                       :db/valueType :db.type/string
                       :db/cardinality :db.cardinality/one
                       :db/unique :db.unique/value
                   }
                   {
                       :db/ident :User/number
                       :db/valueType :db.type/string
                       :db/cardinality :db.cardinality/one
                   }
                   ])
(d/transact connInternal user-schema)


(def user-1-name "User_1")

(def user-data [
  {
    :User/name user-1-name
  }
])
(d/transact connInternal user-data)

(d/transact-async connInternal [[:db/retractEntity [:User/name user-1-name]]])

(def user-1-number "User_Number_1")
(def user-updated-data [
  {
    :db/id [:User/name user-1-name]
    :User/number user-1-number
  }
])
(d/transact connInternal user-updated-data)


We see that the transaction 13194139534653 happened and after execution this transaction the entity looked as:

where :User/name is absent what is expected due to transaction 13194139534652

P.S. Simply interesting: why the number 13194139534651 was not used to identify the second transaction?
P.S.S. Looks like as lookup ref either was resolved by peer or by transactor but within the state of db which was actual when the transaction came to the transactor(when the second transaction were still in progress). But if to read Identity and Uniqueness | Datomic and Transactions | Datomic then the issue is on transactor side
P.S.S.S Lookup refs are used by us as the way to guarantee that the entity still exists

2 Likes

Datomic On-Prem 1.0.6202

Another interesting behavior: if execute the script the second time then the third step returns the excepted error

@nikolayandr Thank you for the report. We have reproduced this behavior and are looking at a fix in the next release of Datomic on-prem. I will update this thread when we have the release and fix in hand.

1 Like

Hi, could you please tell me whether this issue has been resolved?

@nikolayandr yes, this was resolved in 1.0.6527: Change Log | Datomic

  • Fix: Peer no longer resolves lookup refs before sending tx data to transactor.

Sorry for not updating here as soon as the release last year.