5

Goliath (eventmachine) の下で em_mysql2 で activerecord を使用しています。User モデルで最も奇妙なことが起こっています。初めて /users に POST を実行すると、期待どおりに機能します。2 番目の POST を実行すると、エラーが発生します。

Mysql2::Error: This connection is still waiting for a result, try again once you have the result: INSERT INTO `users` (... and so on ...)

これは、他のモデルやルートでは発生しません。データベース接続がめちゃくちゃな状態にある場合、他のリクエストでも同じエラーが表示されると思いますが、いいえ-他のすべてのDB更新およびGETリクエストは正常に機能しているようです。

これが私の Users モデルでのみ User.save アクションでのみ発生する可能性があることを理解している人はいますか? アクティブなレコードは、Model.save を実行するために使用した DB 接続を保存して再利用しますか?

編集:

この質問を書いたとき、ActiveRecord を ORM として使用していたことに言及できませんでした。また、ユーザー認証情報を取得するために Mongo データベースにリクエストを非同期的に送信していたことにも言及しませんでした。

私の解決策:

このエラーが発生するのは、MySQL からの応答よりも前に Mongo からの応答が戻ってきたときだけであり、MySQL の応答が、要求を行ったファイバーとは異なるファイバーによって取得されたことが判明しました。私が使用していた MySQL2 ファイバーの実装では、ファイバーの objectID を使用して接続を管理していたため、問題が発生したようです。

ActiveRecord + MySql2 + Fibers + Goliath の全体的な接続プールは、完全にサポートされている構成ではありませんでした。(その時から多少の進歩はあるかもしれませんが)

4

1 に答える 1

0

em-synchronyに付属している接続プールを使用します。1つの接続で複数のアクティブなクエリを使用することはできないため、MySQLクエリが結果を待機している間にリクエストがGoliathから着信するため、ここでは1つの接続のみを使用すると失敗します。

代わりに、接続を次のようにラップします。

db = EventMachine::Synchrony::ConnectionPool.new(size: 2) do
  Mysql2::EM::Client.new
end

プールは、すべての接続が使用されている場合、接続が使用可能になるまで要求が待機することを確認します。

ただし、データベースが処理できる内容と予想されるトラフィック量に応じて、接続プールのサイズを調整する必要があります。私は5-10前後の何かから始めましたが、少なくとも最初は比較的トラフィ​​ックの少ないサービスでした。それは私たちの接続の問題を解消しました。

于 2011-11-06T21:35:29.337 に答える