elixir-sqlite / exqlite

An SQLite3 driver for Elixir
https://hexdocs.pm/exqlite
MIT License
217 stars 48 forks source link

onboard transaction.exs suite, various transaction fixes #112

Closed kevinlang closed 3 years ago

kevinlang commented 3 years ago

The main test that was failing was this one, which was subsequently blocking the other tests was:

    @tag :transaction_checkout_raises
    test "checkout raises on transaction attempt" do
      assert_raise DBConnection.ConnectionError, ~r"connection was checked out with status", fn ->
        PoolRepo.checkout(fn -> PoolRepo.query!("BEGIN") end)
      end
    end

We assume that all transaction-beginning statements go through our handle_transaction call which is not the case. Here we don't detect we begin a transaction and thus don't know we are in an active transaction at "checkin" time, hence why the error is not thrown.

The fix is to add a new transaction_status NIF call that uses http://www.sqlite.org/c3ref/get_autocommit.html to return the current transaction status, and wiring that up in the correct places.

The second issue was that :disconnect was not properly rolling back a transaction. This is because sqlite3_close_v2 is not guaranteed to succeed, and indeed was going into a "zombie" state, as described at https://www.sqlite.org/c3ref/close.html . The fix for this was to make sure we atleast roll back any active transaction before doing this close logic, and then relying on the GC to clean the open prepared statements.

This closes #93 and likely also closes #58 .