【问题标题】:Problem with Squeryl and Play! framework in scalaSqueryl 和 Play 的问题! scala中的框架
【发布时间】:2011-08-10 03:33:20
【问题描述】:

在将 Squeryl 与 Play! 一起使用时,我遇到了一个奇怪的问题。

正常使用,其他一切正常。但是,如果我在同一个请求中使用多个事务,则会出现错误。

这就是我设置 Squeryl 的方式:

def initDB() {
  import org.squeryl._
  import play.db.DB

  Class.forName("com.mysql.jdbc.Driver")
  SessionFactory.concreteFactory = Some(() =>
    Session.create( DB.getConnection, new MySQLAdapter) )
}

示例交易,也是下面堆栈跟踪中引用的交易:

transaction {
  import models.Game
  Game.planets.insert(planetList) 
  Game.moons.insert(moonList)
}

堆栈跟踪:

Internal Server Error (500) for request GET /generate-galaxy

Execution exception (In /app/Generator.scala around line 330)
SQLException occured : You can't operate on a closed Connection!!!

play.exceptions.JavaExecutionException: You can't operate on a closed Connection!!!
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:228)
    at Invocation.HTTP Request(Play!)
Caused by: java.sql.SQLException: You can't operate on a closed Connection!!!
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:106)
    at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65)
    at org.squeryl.dsl.QueryDsl$class._executeTransactionWithin(QueryDsl.scala:95)
    at org.squeryl.dsl.QueryDsl$class.transaction(QueryDsl.scala:64)
    at org.squeryl.PrimitiveTypeMode$.transaction(PrimitiveTypeMode.scala:40)
    at generator.Generator$$anonfun$generatePlanets$2.apply(Generator.scala:330)
    at generator.Generator$$anonfun$generatePlanets$2.apply(Generator.scala:55)
    at generator.Generator$.generatePlanets(Generator.scala:55)
    at generator.Generator$.generateGalaxy(Generator.scala:36)
    at controllers.MainRouter$.generateGalaxy(MainRouter.scala:29)
    at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:543)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:499)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:493)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:470)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:158)
    ... 1 more
Caused by: java.lang.NullPointerException
    ... 14 more

我知道问题不在我的查询中,因为在使用 scalatra 作为 Web 框架时它们运行良好。我可以将所有内容都放入一个事务块中,但这并不是很优雅,我也不确定它是否适用于这种情况 - planetList 列表有大约 300 万成员,这导致在我将数据库插入拆分为 50k 个元素的较小块之前,scala 内存不足。

【问题讨论】:

  • 你得到答案了吗?我遇到了同样的问题。
  • IIRC,我只是诉诸于只使用一次交易。
  • 我遇到了很多同样的问题,尽管我的问题有点不同而且更简单。当我通过 RenderArgs 传递一个 Squeryl 值时,它似乎保存了整个该死的 SQL 查询并尝试再次运行它......而不是仅仅传递该值。如果您找到更简单的解决方法,请告诉我。

标签: scala playframework squeryl


【解决方案1】:

您能否将您的问题重新发布到Squeryl mailing list?我不熟悉玩!但我知道其他一些用户和提交者是。如果您可以将示例项目发布到 GitHub 并包含一个也会有帮助的链接。

【讨论】:

    【解决方案2】:

    我想看看第一个 tx 是如何关联的,它之前会立即执行吗? 它们是嵌套的吗?

    当您有 2 笔交易时,您可以这样做:

    val s1 = Session.create( DB.getConnection, new MySQLAdapter) )
    val s2 = Session.create( DB.getConnection, new MySQLAdapter) )
    
    
    using(s1) {...   .... s1.connection.commit}
    using(s2) {...   .... s1.connection.commit}
    

    【讨论】:

    • 事务是串行执行的:完成一些处理,然后将其提交到数据库,再进行一些处理,写入数据库等。我以为我应该每个请求只使用一个会话。
    猜你喜欢
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 2014-02-21
    • 2016-07-08
    • 1970-01-01
    • 2013-05-27
    • 2015-01-20
    • 1970-01-01
    相关资源
    最近更新 更多