**Software Versions:**
Rails 3.1.3
MySQL 5.5.21
OS: MacOS 10.7.3
今天我用 foreigner gem 向我的 MySQL 数据库添加了很多外键约束。 但是现在我在简单插入时得到“锁定等待超时”异常:
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)
如果我只是创建没有“SubData”的“PrimaryData”,或者分别创建“PrimaryData”和“SubData”,那么我不会收到任何 MySQL 错误,只有当我尝试使用一些“SubData”创建“PrimaryData”时” 以 Rails 的“accepts_nested_attributes_for”方式。
谁能帮我解决这个问题? 提前致谢。
最佳答案
这是一个死锁。
当您在具有外键约束的表中添加一行时,MySQL 将同时获取此表(或 InnoDB 中的行)和引用表(或 InnoDB 中的行)的锁。
在这种特殊情况下,当您使用 SubData 创建 PrimaryData 时,MySQL 首先获取 primary_data 的锁,然后获取 sub_data 的锁,然后在获取 primary_data 的另一个锁时死锁。
一般来说,在 Rails 中使用外键并不是一个好主意。将事件记录验证器用于这些目的。
关于MySQL 外键约束在我的 Rails 3.1 应用程序中抛出 ActiveRecord::StatementInvalid(锁定等待超时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9449256/