-
Notifications
You must be signed in to change notification settings - Fork 48
Question: Is it possible to use immediate transactions? #151
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Great question, yes it is 100% now You need to set the transaction mode to Check out the transaction documentation for Ecto in general https://github.com/elixir-sqlite/exqlite/blob/fec606ccc8a291526d1e3137099b6acf0f6f84fe/lib/exqlite/connection.ex#L263-L280 EDIT: Something like this |
I wonder if it is possible to set the default transaction mode for ecto rather than being forced to pass it everytime. I will need to dig further. |
@josevalim or @ruslandoga or @greg-rychlewski what is your opinion on setting the default transaction mode for this adapter to |
I am trying to set the iex(4)> Repo.insert(%Person{name: "Cristian"}, mode: :immediate)
# [debug] QUERY OK source="persons" db=0.8ms idle=936.3ms
# INSERT INTO "persons" ("name") VALUES (?) RETURNING "id" ["Cristian"]
iex(5)> Repo.transaction fn repo ->
...(5)> repo.insert(%Person{name: "Cristian"}, mode: :immediate)
...(5)> end
# [debug] QUERY OK db=0.0ms idle=1807.7ms
# begin []
# ↳ :erl_eval.do_apply/7, at: erl_eval.erl:746
# [debug] QUERY OK source="persons" db=0.7ms
# INSERT INTO "persons" ("name") VALUES (?) RETURNING "id" ["Cristian"]
# ↳ anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4, at: # lib/ecto/adapters/sql.ex:1382
# [debug] QUERY OK db=0.2ms
# commit []
|
I don't know if the debug logs spit out the |
Oh that makes sense. I will dig further. |
I do remember looking into this when I was first implementing this https://www.sqlite.org/lang_transaction.html My goal was maximum read/write throughput. I opted for
|
I would personally prefer to have the defaults match SQLite's, but since this adapter already uses WAL mode and foreign keys by default, I think it would be consistent to pick a transaction mode that works better in Ecto applications by default as well. We'll just need to make sure that reads don't start explicit transactions or if they do, they are not immediate. That might require some changes. |
That would definitely have to happen. EDIT: I personally think it is wiser to leave that up to the caller to explicitly call out an exclusive or immediate lock is desired, but err on the side of deferred. I could document this better in the readme to point out the pitfalls of using the different modes and let the programmer decide when to use the mode. |
Regarding the logging, DBConnection used to log But it requires the adapter to changes its return value from |
FWIW I feel like it's enough for a library to document the option, say briefly what it controls and then link to the database docs to get more information. In my experience, documenting things like pitfalls tends to have the same issue as online tutorials where they can become out of date. People should ideally not rely on Ecto to teach them how to use their database. That should be knowledge they have before touching Ecto. That's just my $0.02 though. It's obviously your call! |
I'd really love it if the default transaction mode could be a configurable option in the Ecto.Adapters.SQLite3 config (rather than having to specify immediate on every transaction invoke individually). I use BEGIN IMMEDIATE for all my SQLite transactions across the board for this reason: https://kerkour.com/sqlite-for-servers#use-immediate-transactions |
Would something like this work instead of adding extra configuration options? defmodule MyApp.Repo do
use Ecto.Repo, adapter: Ecto.Adapters.SQLite3, otp_app: :my_app
def immediate_transaction(fun_or_multi) do
transaction(fun_or_multi, mode: :immediate)
end
end |
Good call! That definitely works too :) |
@ruslandoga, that's actually a super simple solution... I wish I had thought of it. |
Yeah that's a great idea. Should we close this issue then? |
Yea. |
Uh oh!
There was an error while loading. Please reload this page.
Ruby on Rails is making many changes to improve SQLite support. Apparently, one of the most noticeable is using
BEGIN IMMEDIATE TRANSACTION
. Quoting from this article from the author of such improvements for RoR (it is a highly recommended read for anyone using SQLite):The he goes about how 99% of the time starting a transaction in Ruby on Rails means that there will be a database write. The conclusion is that immediate transactions should be the default for most cases.
This made me wonder a few things:
The text was updated successfully, but these errors were encountered: