2011-08-04 58 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