2012-02-25 70 views
4
**Software Versions:** 

Rails 3.1.3 
MySQL 5.5.21 
OS: MacOS 10.7.3 

今天,我加入了很多的外键约束与外国人宝石我的MySQL数据库。 但现在我得到简单插入“锁定等待超时”例外:MySQL的外键约束在我的Rails的ActiveRecord抛出:: StatementInvalid(锁等待超时)3.1应用

ActiveRecord::StatementInvalid (Mysql2::Error: Lock wait timeout exceeded; 
try restarting transaction 

如果我从数据库中删除外键约束上的问题了。

当我试图用数据添加对象的“HAS_ONE”伴随“accepts_nested_attributes_for”的问题发生:

class MyApp::PrimaryData < ActiveRecord::Base 
    has_one :sub_data, :dependent => :destroy 
    accepts_nested_attributes_for :sub_data 
    [...] 
end 

class MyApp::SubData < ActiveRecord::Base 
    belongs_to :primary_data 
    attr_accessible :field1, :field2 
    [...] 
end 

table: primary_data 
------------------- 
- id (integer) 
- field1 (string) 
    [...] 


table: sub_data 
--------------- 
- id (integer) 
- primary_data_id (integer) 
- field1 (string) 
- field2 (string) 
    [...] 

-> foreign_key_contraint on primary_data_id --> table primary_datas (id) 

如果我只是创建了“PrimaryData”无“子数据”,或“PrimaryData”和“子数据”分开,那么我不会收到MySQL错误,只有当我尝试通过Rails“accep_nested_attributes_for”方式创建带有“子数据”的“PrimaryData”时。

有没有人可以帮助我解决这个问题? 在此先感谢。

+0

我想我以前见过这个问题,但我不太清楚在什么情况下;它与你所描述的不一样。我似乎记得我通过简单的服务器和MySql重启来解决了我的问题。我可能是错的,但... – Pete 2012-04-20 15:55:37

+0

你使用哪个引擎? InnoDB或MyISAM?当应用程序崩溃时,您可以发布日志样本吗?如果当然不是太晚:) – basgys 2012-09-15 16:49:35

回答

-2

这是一个僵局。

当您在具有外键约束的表中添加行时,MySQL将在此表(或InnoDB的情况下的行)和引用的表(或InnoDB的情况下的行)上获取锁。

在这种特殊情况下,当您使用SubData创建PrimaryData时,MySQL首先在primary_data上获取锁,然后在sub_data上获取锁,然后在primary_data上获取另一个锁时死锁。

一般来说,使用带有rails的外键不是一个好主意。用于这些目的的活动记录验证程序。

+0

在数据库级**以及在应用程序级实施参照完整性几乎总是一个好主意。程序员犯错误,并且由于**数据库强制**外键而在运行时获得异常要比由于所述错误而丢失有价值的生产数据要好。 – silasjmatson 2013-03-14 18:34:54

+0

你错了。 你的建议在理论上是好的,但不是在实践中。在大规模系统中,你希望数据库尽可能少做工作,其他方面你永远不会达到规模。 解决这个难题的方法是除了应用程序级别完整性检查之外,还要定期进行数据库完整性检查。 这也使您的应用程序不再与特定的数据库实现紧密耦合并实现模块化。 – 2013-03-18 20:06:49