Squeryl和Play的问题! scala中的框架

时间:2011-08-04 17:40:18

标签: scala playframework squeryl

使用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耗尽内存。

2 个答案:

答案 0 :(得分:1)

您能否将问题重新发布到Squeryl mailing list?我不熟悉Play!但我知道其他一些用户和通讯员都是。如果您可以将示例项目发布到GitHub并包含一个有用的链接。

答案 1 :(得分:1)

我想看看第一个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}