Rails何时用BEGIN和COMMIT包装插入?

问题描述 投票:3回答:3

我正在尝试优化我的数据库调用以进行长期rake任务,因此我一直在分析每个查询。

我注意到Rails经常用BEGINCOMMIT包装我的插入和更新。我没有在任何地方使用.transaction所以我很困惑为什么会发生这种情况。我已禁用我的after_saveafter_commit日志记录,但这似乎没有效果。

有任何想法吗?亚马逊网络服务测量每一个MySQL I / O,所以我想摆脱这些BEGINCOMMIT语句。

谢谢!

mysql ruby-on-rails ruby amazon-web-services
3个回答
5
投票

Rails将每个写入封装在一个事务中。例:

Foo.create
Foo.create
Foo.create

日志:

 (0.1ms)  BEGIN
SQL (6.9ms)  INSERT INTO `foos` VALUES ()
 (3.3ms)  COMMIT

 (0.2ms)  BEGIN
SQL (8.0ms)  INSERT INTO `foos` VALUES ()
 (0.4ms)  COMMIT

 (0.2ms)  BEGIN
SQL (7.3ms)  INSERT INTO `foos` VALUES ()
 (1.3ms)  COMMIT

如果你将这些调用包装在explicit transaction中,Rails将使用该事务而不是创建新的事务:

Foo.transaction do
  Foo.create
  Foo.create
  Foo.create
end

日志:

 (0.2ms)  BEGIN
SQL (0.3ms)  INSERT INTO `foos` VALUES ()
SQL (0.2ms)  INSERT INTO `foos` VALUES ()
SQL (0.2ms)  INSERT INTO `foos` VALUES ()
 (6.7ms)  COMMIT

3
投票

你实际上并不想摆脱它们。 Active Record在幕后扮演了很多魔力,因此在保存复杂模型/关系时,如果出现问题,事务包装器对于撤消数据库更改非常有用。

注意,这与你使用.transaction无关。 Active Record会在数据库事务中自动包含.save.update_attribute等常用操作。


2
投票

BEGIN和COMMIT并不是一个过载,而是我必须说的救星。如果出现问题,它们可以帮助您回滚事务。虽然你没有使用.transaction,但它们默认是作为Rails的背景魔法实现的。

如果您真的想在AWS服务上节省成本,请尝试删除不会妨碍您的应用程序安全性和健壮性的内容。

© www.soinside.com 2019 - 2024. All rights reserved.