我正在尝试使用ActiveRecord::Base.transaction
. 我认为使用 Rails 1.2.6 和 mysql 5.0 默认情况下回滚不起作用。多玩一点,我发现autocommit
在 mysql 连接中没有设置为 0。
问题:
1)如何禁用所有连接的rails中的自动提交?
2)它会对其他不必是事务性的代码产生一些负面影响吗?
我正在尝试使用ActiveRecord::Base.transaction
. 我认为使用 Rails 1.2.6 和 mysql 5.0 默认情况下回滚不起作用。多玩一点,我发现autocommit
在 mysql 连接中没有设置为 0。
问题:
1)如何禁用所有连接的rails中的自动提交?
2)它会对其他不必是事务性的代码产生一些负面影响吗?
如果您有需要显式事务的代码和可以依赖自动提交的代码的混合,也许您不应该为所有连接禁用自动提交。您走在正确的轨道上,想知道这是否会影响其他代码。如果您禁用自动提交,但其他代码不知道它必须提交才能提交其工作,那么这将是一个问题。当连接关闭时,未提交的工作将回滚。
您应该知道 MySQL 的默认存储引擎是MyISAM,它根本不支持事务。当您对使用 MyISAM 的表进行更改时,无论您对开始和完成事务的显式请求如何,也无论自动提交的状态如何,更改都会立即有效地提交。因此,无论如何您都无法回滚,除非您使用InnoDB存储引擎(或其他事务安全存储引擎,例如BDB)创建表。
在 MySQL 中使用事务不需要禁用自动提交模式。只需明确地开始交易。在您提交或回滚该事务之前,以下 SQL 语句将成为事务的一部分,无论您当前连接上的 autocommit 值如何。
http://dev.mysql.com/doc/refman/5.0/en/commit.html说:
使用 START TRANSACTION,自动提交保持禁用状态,直到您使用 COMMIT 或 ROLLBACK 结束事务。然后自动提交模式恢复到之前的状态。
您不必禁用自动提交即可使用事务。当您启动事务自动提交设置没有任何区别时,您必须明确地 COMMIT 或 ROLLBACK。此外,禁用自动提交会影响您的非事务性代码。
正确答案。我在交易开始时在我的代码中执行 DROP TABLE IF EXISTS。MySQL 似乎对事务中的 DROP 语句有问题:
http://bugs.mysql.com/bug.php?id=989
有趣的是,我猜到了在 DROP 语句之前发送“SET aucotommit = 0”的问题的正确解决方法。
谢谢您的帮助
并不是说我有任何特别不是事务性的代码 - 它主要是所有 ActiveRecord 对象,如果我的方法之一失败,我只想有回滚行为。
我会探索更多,你似乎是对的 - 我可以在 mysql 控制台中确认你的答案。但是,在我的 Rails 应用程序中,我必须执行 connection.execute("set autocommit = 0") 才能使回滚工作。