Как отменить или отменить транзакцию в datomic?


Я случайно совершил транзакцию в datomic и хочу "отменить" всю транзакцию. Я точно знаю, какая это транзакция, и я могу видеть ее датомы, но я не знаю, как перейти оттуда к откатной транзакции.

1 13

1 ответ:

Основная процедура:

  1. извлеките данные, созданные в транзакции, которую вы хотите отменить. Используйте журнал транзакций, чтобы найти их.
  2. Удалите данные, связанные с самой сущностью транзакции: мы не хотим удалять метаданные транзакции.
  3. инвертировать "добавленное" состояние всех оставшихся датомов, то есть, если был добавлен датом, убрать его, а если он был убран, добавить его.
  4. измените порядок инвертированных данных таким образом, чтобы новое плохое значение было убрано перед старым хорошим ценность утверждается заново.
  5. зафиксируйте новую транзакцию.

В Clojure ваш код будет выглядеть следующим образом:

(defn rollback
  "Reassert retracted datoms and retract asserted datoms in a transaction,
  effectively \"undoing\" the transaction.

  WARNING: *very* naive function!"
  [conn tx]
  (let [tx-log (-> conn d/log (d/tx-range tx nil) first) ; find the transaction
        txid   (-> tx-log :t d/t->tx) ; get the transaction entity id
        newdata (->> (:data tx-log)   ; get the datoms from the transaction
                     (remove #(= (:e %) txid)) ; remove transaction-metadata datoms
                     ; invert the datoms add/retract state.
                     (map #(do [(if (:added %) :db/retract :db/add) (:e %) (:a %) (:v %)]))
                     reverse)] ; reverse order of inverted datoms.
    @(d/transact conn newdata)))  ; commit new datoms.