Fork me on GitHub
#xtdb
<
2022-11-18
>
macrobartfast01:11:29

Has the answer by C. Grote been superseded by any new functionality? (and I’m open to other approaches) https://stackoverflow.com/questions/69291427/how-do-you-update-a-single-value-in-xtdb

Jacob O'Bryant02:11:53

Transaction functions are still a good way to do it. Another method is via https://docs.xtdb.com/language-reference/datalog-transactions/#match (i.e. do the same thing as in that SO question, but add a match so that you don't lose any data if two transactions try to update the same doc concurrently). And then you if the match fails, you can redo the transaction after querying for the document's new value. Biff takes that approach.

πŸ‘ 1
πŸ™ 1
Lyn Headley03:12:41

I thought the preferred method in biff was to use :db/op :update and pass in a single field

Jacob O'Bryant04:12:54

Yes, but under the hood that gets translated into match + put + retries

Jacob O'Bryant04:12:15

There's a biff/biff-tx->xt function you can use to see what the transaction looks like after it gets translated by the way, for example:

(let [{:keys [biff/db] :as sys} (get-sys)
      user-id (biff/lookup-id db :user/email "")]
  (biff/biff-tx->xt
   sys
   [{:db/doc-type :user
     :db/op :update
     :xt/id user-id
     :user/email ""}]))

=> ([:xtdb.api/match
     #uuid "122c07db-1c20-446b-91b1-0817f0a86faa"
     {:user/email "",
      :user/foo "Some Value",
      :user/joined-at #inst "2022-12-10T00:54:02.831-00:00",
      :xt/id #uuid "122c07db-1c20-446b-91b1-0817f0a86faa"}]
    [:xtdb.api/put
     {:user/email "",
      :user/foo "Some Value",
      :user/joined-at #inst "2022-12-10T00:54:02.831-00:00",
      :xt/id #uuid "122c07db-1c20-446b-91b1-0817f0a86faa"}])

😎 1
rickmoynihan09:11:02

How does xtdb enforce a total ordering over transaction time, if transaction time is based on system time? β€’ Firstly does xtdb have a single transactor (like datomic)? If it does how does it: 1. Break ties if two transaction requests are received concurrently? 2. Ensure that transaction time is monotonically increasing after deciding an order of events? i.e. how does it ensure that transaction time is a total order; not just a partial order; or is a partial order somehow ok? Finally If it supports committing concurrent transactions; how does it break ties?

rickmoynihan09:11:23

ok just seen the architecture diagram (which implies a single transactor) and this comment: > the transaction time provided is no earlier than any other transaction currently in the system - i.e. transaction times must be increasing. https://docs.xtdb.com/language-reference/datalog-transactions/#transaction-time Which implies to me a total order - but that it’s on the application/loader to convert any partial ordering on tx-time into a total order.

jarohen11:11:28

Hey @U06HHF230 πŸ‘‹ As you suspected, yes - XT is a single-threaded writer system. Transaction time may not be monotonically increasing (it's possible for two consecutive transactions to have the same timestamp) - instead we use transaction id to break ties (which is monotonically increasing), and this is what gives us the total order

jarohen11:11:14

this tx-id is provided to us by the transaction log (e.g. Kafka) - it's not something users can override

rickmoynihan11:11:15

ah ok thanks β€” the possibility for timestamps to be the same is exactly the problem I was highlighting β€” and the presence of a monotonically increasing tx-id is the missing piece I was looking for. Thanks πŸ™‡ . Can you use tx-id in queries; to join / compare transactions inside the query language?

rickmoynihan11:11:39

(obviously you’d be able to compare outside yourself)

jarohen11:11:05

what do you mean 'to join/compare transactions' btw?

rickmoynihan14:11:14

Can you compare the state of the world at T1 with the state of the world at T2 in a normal query (not within a transaction)?

jarohen15:11:16

not within a single query, unfortunately - you could do it with two queries (with two separate DB snapshots) and then compare the results in Clojure, for example

jarohen15:11:56

or, if you know the entity ids whose difference you're interested in, xt/entity-history might be your friend

πŸ‘ 1