1

Slick 2.0.1 と play-slick 0.6.0.1 でのセッションと接続の処理に問題があります

エラーは

[SQLException: Timed out waiting for a free available connection.]
[...]
Caused by: java.sql.SQLException: Timed out waiting for a free available connection.
    at com.jolbox.bonecp.DefaultConnectionStrategy.getConnectionInternal(DefaultConnectionStrategy.java:88) ~[bonecp.jar:na]
[...]

明示的なセッションを 1 か所でセットアップするためのプレイ ベース コントローラー トレイトがあります。

trait BaseController extends Controller with Secured {
    import play.api.Play.current
    implicit def session: SessionDef = play.api.db.slick.DB.withSession {
        implicit session => {session}
    }
}

次に、明示的なセッションを使用して UserService を単純に呼び出す /list アクションがあります。

object List extends BaseController with Secured {
  def index = IsAuthenticated { username =>
    implicit request =>
    UserService.findByEmail(username).map { user =>
      Ok(views.html.List.index(user))
    }.getOrElse(Forbidden)
  }
}

すべての非同期アクションを削除したので、この質問が同様の質問と重複するとは思わない: Play slick and Async - is a race condition? またはScala Play 2.2 Slick 1.0.1 - future { {Try {...} } 使用可能な空き接続を待ってタイムアウトしました

この問題は、アクションを約 10 回リロードした後に発生します。

明らかに、slick のセッション処理で何か間違ったことをしています - playframework での slick 2 セッション処理の良い例はありますか? そのためのベストプラクティスは何ですか?

編集:問題の考えられる原因の 1 つは、TableQueries を保持するために使用するオブジェクトである可能性があります

object Models {
    val users = TableQuery[Users]
    val mailinglists = TableQuery[Mailinglists]
    val mailinglistMemberships = TableQuery[MailinglistMemberships]
}

それが問題の原因である可能性がある場合、これらの参照を配置するのに適した場所は何ですか? オブジェクトの主な理由は、テーブル定義の外部キーでこれらのインスタンスを参照することです ( http://slick.typesafe.com/doc/2.0.1/schemas.html#constraintsと同様) 。

編集:これが findByEmail のコードです - しかし、それは本当に重要ではないと思います。すべてのクエリで同じ動作と問題のようです。

def findByEmail(email: String)(implicit session: Session): Option[User]
  = Models.users.filter(_.email === email).firstOption

正しい方向へのヒントに感謝します。

4

2 に答える 2

0

問題は、BaseControllerトレイトの暗黙的なセッション定義にありました。セッション定義は、コントローラー レベルではなくアクション レベルである必要があるようです。残念ながら、その理由は (まだ) 説明できません。

trait BaseController extends Controller with Secured {
    //REMOVED this code
    //import play.api.Play.current
    //implicit def session: SessionDef = play.api.db.slick.DB.withSession {
    //    implicit session => {session}
    //}
}

Helped を使用してコントローラー アクションを更新しDbActionました - 接続タイムアウトは発生しません。

trait Application extends Controller {
  def index = DBAction { implicit request =>
    request.session.get("email") flatMap (email => UserService.findByEmail(email)) map { user =>
      Ok(views.html.index(user))
    } getOrElse {
      Ok(views.html.index(null))
    }
  }
}

object Application extends Controller with Application

したがって、まだ欠けているのは、認証されたアクションとプレイスリックの混合DBActionです。まったく同じ質問がここで尋ねられました:認証されたアクションで滑らかな dbaction を構成します

たぶん、巧妙な/遊び上手なチームの誰かが介入して、これらの質問に答えることができますか?

于 2014-04-05T12:39:32.757 に答える
0

私も同じ問題に直面しました.アプリケーションが接続プールから接続を取得していないようです.だから私は設定を使用しました:

db.default.partitionCount=1  
db.default.maxConnectionsPerPartition=20 
db.default.minConnectionsPerPartition=10 
db.default.acquireIncrement=1    
db.default.acquireRetryAttempts=5 
db.default.acquireRetryDelay=5 seconds 
db.default.acquireRetryDelay=5 seconds
db.default.idleMaxAge=10 minute 
db.default.idleConnectionTestPeriod=5 minutes 
db.default.initSQL="SELECT 1" 
db.default.maxConnectionAge=1 hour

その後、エラーが発生することはありません(利用可能な空き接続を待ってタイムアウトしました)。(postgresデータベースを使用してherokuにデプロイされたアプリケーション)

于 2014-03-25T16:15:32.710 に答える