2011-08-04 28 views
4

我有一个好奇的问题时使用Squeryl与Play !.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万个成员,这导致scala在内存耗尽之前我将数据库插入分为50k个元素的较小块。

+0

你有没有得到答案?我遇到了同样的问题。 – Ladlestein

+0

IIRC,我只使用过一次交易。 – Mononofu

+0

虽然我的问题有点不同,但我也遇到过很多这个相同的问题。当我通过RenderArgs传递一个Squeryl值时,它似乎保存了整个该死的SQL查询并尝试再次运行它,而不仅仅是传递值。让我知道如果你找到一个更简单的修复。 – crockpotveggies

回答

1

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

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} 
+0

事务是连续执行的:一些处理完成,然后它被提交到数据库,进行一些更多的处理,写入数据库等。 我以为我应该每个请求只使用一个会话。 – Mononofu