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

Rails 3.1.3 
MySQL 5.5.21 
OS: MacOS 10.7.3 

今日、私は外国人の宝石と多くの外来キー制約をMySQL DBに追加しました。 しかし、今、私は、単純な挿入の「ロック待ちタイムアウト」の例外を取得:MySQLの外部キーの制約により、Rails 3.1アプリケーションでActiveRecord :: StatementInvalid(ロック待ちタイムアウト)が発生する

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

私は私のDBから外部キーcontraintsを削除した場合、問題がなくなっています。

i "がaccepts_nested_attributes_for" と "has_oneの" 関連のデータを持つオブジェクトを追加しようとすると問題が起こる:私はせずに "PrimaryData" を作成した場合

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"と "SubData"を別々に取得すると、MySQLのエラーは発生しません。ただし、 "PrimaryData"をいくつかの "SubData"を使って "accepts_nested_attributes_for"に作成しようとしています。

誰でもこの問題を解決できますか? ありがとうございます。

+0

私は前にこの問題を見たことがあると思いますが、私はかなりの文脈で覚えていません。それはあなたが記述したものと同じではありませんでした。私はサーバーとMySqlの簡単な再起動で私の問題を解決したことを覚えているようだ。私は間違っているかもしれません... – Pete

+0

どのエンジンを使用しますか? InnoDBまたはMyISAM?アプリクラッシュ時にログのサンプルを投稿できますか?あまり遅れていないのであれば:) – basgys

答えて

-2

これはデッドロックです。

外部キー制約のあるテーブルに行を追加すると、MySQLはこのテーブル(InnoDBの場合はロー)と参照されるテーブル(InnoDBの場合はロー)の両方でロックを取得します。

SubDataでPrimaryDataを作成すると、MySQLはまずprimary_dataと次にsub_dataでロックを取得し、次にprimary_dataで別のロックを取得するとデッドロックします。

一般に、外部キーをレールで使用することはお勧めできません。これらの目的には、アクティブレコードバリデータを使用します。

+0

データベースレベルでの参照整合性の強化**は、アプリケーションレベルと同様に**ほぼ常に良い考えです。プログラマは間違いを犯し、実行時に**データベース強制**外部キーのために例外を得ることは、間違いのために貴重な生産データを失うことよりも優れています。 – silasjmatson

+0

あなたは間違っています。 あなたの提案は理論上は良いですが、実際はそうではありません。大規模なシステムでは、データベースの作業をできるだけ少ないものにしたいと考えています。 このジレンマの解決策は、アプリケーションレベルの完全性チェックに加えて、定期的なデータベースの完全性チェックを行うことです。 これにより、アプリケーションの特定のデータベース実装との結合が緩和され、モジュール性が実現されます。 –

関連する問題