2013-04-26 62 views
4

如果我有一堆正在执行的查询,包装在一个Activerecord事务中,那么所有发送到数据库的查询都是一次往返(即发送到db的所有查询和发回的响应),还是每个查询每次需要一次旅行?ActiveRecord交易只需往返1次数据库?

例如代码:

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

如果是后者,有一种方法强制事务内的所有查询在1个往返要执行?

+0

是你查询所有的原始SQL字符串吗? – jstim 2013-04-26 03:05:11

+0

是的,他们是原始的SQL – 2013-05-13 01:25:59

回答

5

ActiveRecord::Base.transaction通话将两次调用数据库:

  • 一个告诉数据库开始交易。
  • 另一个块在退出时告诉数据库提交或回滚事务。

每个ActiveRecord::Base.connection.execute调用也跟数据库通话。这必须发生在您execute可能引发异常或返回有用数据的查询中。通常,每条SQL语句都是对数据库的单独调用(即往返)。

虽然只会使用一个数据库连接

1

MySQL会阻止您在旅途中执行多个查询(这的确可以缓解一些讨厌的SQL注入的可能性,如little bobby tables

如果你的数据库支持的话,理论上你可以把它全部一气呵成:

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

注 “理论上是这样。” 在不要尝试这样做。


如果有人想知道发生了什么事情在那里。

查询=您的查询

ARR = ["BEGIN",*query,"COMMIT",""]的阵列只是平展查询到数组。

arr*";\n"arr.join(";\n")相同数组末尾的空白提供尾随的“;”对于COMMIT。

这对Ruby Golf这样的游戏很有趣,但不要在生产中使用它。你只会伤害那些试图在将来阅读你的代码(甚至是未来你的代码)。