Are ActiveRecord transactions just one database hit?

If I have a bunch of requests that I execute wrapped in an Activerecord transaction, all these requests are sent to the database in one round (i.e. all requests sent to db and the response is sent back), or each request takes 1 trip every?

Code example:

ActiveRecord::Base.transaction do queries.each do |query| ActiveRecord::Base.connection.execute(query) end end 

If the latter, is there a way to make all requests inside a transaction run in round 1?

+4
source share
2 answers

In an ActiveRecord::Base.transaction call, two database ActiveRecord::Base.transaction will be made:

  • One to inform the database of the start of the transaction.
  • And one more, when the block exits to inform the database about the completion or rollback of the transaction.

Each call to ActiveRecord::Base.connection.execute also talks to the database. This should happen as queries that you execute could throw exceptions or return useful data. In general, each SQL statement is a separate call (i.e. Roundtrip) to the database.

Only one database connection will be used.

+5
source

MySQL will not allow you to execute multiple queries on a trip (which mitigates some of the unpleasant features of SQL injection, such as small bobby tables ;)

If your database supports it, you can in theory send everything in one go:

 ActiveRecord::Base.connection.execute(["BEGIN",*query,"COMMIT",""]*";\n") 

Pay attention to "theoretically." Don't really try to do this.


If someone wonders what is going on there.

query = array of queries

arr = ["BEGIN",*query,"COMMIT",""] just aligns the request in an array.

arr*";\n" is the same as arr.join(";\n") blank at the end of the array provides the final ";" for COMMIT.

It's fun for something like Ruby Golf, but don't use it in production. You will only be ill if you try to read your code in the future (even in the future.)

+1
source

All Articles