4

Activerecord トランザクションにラップされた実行中のクエリが多数ある場合、これらのクエリはすべて 1 回の往復でデータベースに送信されますか (つまり、すべてのクエリが db に送信され、応答が返されます)、または各クエリが使用されますか?それぞれ1回?

コード例:

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

後者の場合、トランザクション内のすべてのクエリを強制的に 1 回の往復で実行する方法はありますか?

4

2 に答える 2

5

このActiveRecord::Base.transaction呼び出しは、データベースに対して 2 つの呼び出しを行います。

  • データベースにトランザクションを開始するように指示するもの。
  • ブロックが終了すると、データベースにトランザクションをコミットまたはロールバックするように指示します。

ActiveRecord::Base.connection.execute呼び出しは、データベースとも対話します。executeこれは、例外を発生させたり、有用なデータを返したりするクエリとして発生する必要があります。一般に、各 SQL ステートメントは、データベースへの個別の呼び出し (ラウンドトリップ) です。

ただし、使用されるデータベース接続は 1 つだけです。

于 2013-04-26T03:07:35.563 に答える
1

MySQL は、旅行中に複数のクエリを実行することを防ぎます (これにより、小さなボビー テーブルなどの厄介な SQL インジェクションの可能性が軽減されます;)

DB がサポートしている場合、理論的にはすべてを一度に送信できます。

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

「理論上」に注意してください。実際にこのようにしようとしないでください。


誰かがそこで何が起こっているのか疑問に思っている場合。

query = クエリの配列

arr=["BEGIN",*query,"COMMIT",""] は、クエリを配列にフラット化するだけです。

arr*";\n" 配列の末尾の空白はarr.join(";\n") 、末尾の「;」を提供します。コミットのために。

これは Ruby Golf のようなものにとっては楽しいものですが、本番環境では使用しないでください。将来あなたのコードを読もうとする人を傷つけるだけです (将来のあなたでさえも)。

于 2013-04-26T04:38:38.367 に答える