Fork me on GitHub
#sql
<
2023-03-05
>
Ludwig20:03:22

Hi! why is the transaction not rolling back? I'm using next.jdbc "1.3.847" and MySQL with InnoDb, which supports transactions, I have tried several ways but not success.

(deftest rollback-test
  (let [db-spec {:jdbcUrl "jdbc:"}]
    (is (= [#:product{:id_product 61}] (jdbc/execute! db-spec ["select id_product from product limit 1"])))
    (binding [next.jdbc.transaction/*nested-tx* :ignore]
      (jdbc/with-transaction [tx db-spec {:rollback-only true}]
        (is (= [#:product{:id_product 61}] (jdbc/execute! tx ["select id_product from product limit 1"])))
        (.setAutoCommit tx false)
        (is (= false (.getAutoCommit tx)))
        (jdbc/execute-one! tx ["truncate product"])
        (.rollback tx)))
    (is (= [#:product{:id_product 61}] (jdbc/execute! db-spec ["select id_product from product limit 1"])))))

seancorfield20:03:33

Several questions here: why are you messing with auto commit? Why are you explicitly trying to roll back the transaction?

seancorfield20:03:50

Have you tried delete from instead of truncate?

seancorfield20:03:32

I ask the latter in case MySQL treats truncate as ddl rather than regular SQL - ddl can't be rolled back in transactions

Ludwig20:03:53

I just tried with serveral ways, with explicit and implicit (commenting out) auto-commit and rollback Also tried with delete instead of truncate, also without the nested-tx binding but it doesn't rollback neither

(deftest rollback-test
  (let [db-spec {:jdbcUrl "jdbc:"}]
    (is (= [#:product{:id_product 61}] (jdbc/execute! db-spec ["select id_product from product limit 1"])))
    (binding [next.jdbc.transaction/*nested-tx* :ignore]
      (jdbc/with-transaction [tx db-spec {:rollback-only true}]
        (is (= [#:product{:id_product 61}] (jdbc/execute! tx ["select id_product from product limit 1"])))
        (jdbc/execute! tx ["delete from product where id_product = ?" 61])))
    (is (= [#:product{:id_product 61}] (jdbc/execute! db-spec ["select id_product from product limit 1"])))))

seancorfield20:03:05

Why are you binding the nested tx Var here? Is there an outer tx in your fixtures?

Ludwig20:03:08

the db already has fix data, I have tried without the binding too, but it doesn't rollback either

Ludwig20:03:20

ah my bad, found the issue as you guessed right, truncate doesn't work. I have tried again with delete without the binding and now it does the rollback

(deftest rollback-test
  (let [db-spec {:jdbcUrl "jdbc:"}]
    (is (= [#:product{:id_product 61}] (jdbc/execute! db-spec ["select id_product from product limit 1"])))
    (jdbc/with-transaction [tx db-spec {:rollback-only true}]
      (is (= [#:product{:id_product 61}] (jdbc/execute! tx ["select id_product from product limit 1"])))
      (jdbc/execute! tx ["delete from product where id_product = ? " 61]))
    (is (= [#:product{:id_product 61}] (jdbc/execute! db-spec ["select id_product from product limit 1"])))))

Ludwig20:03:35

thanks a lot!

2