【问题标题】:Play 2 transaction per request每个请求播放 2 笔交易
【发布时间】:2014-06-07 11:08:50
【问题描述】:

对我来说最方便的事务管理是对整个 http 请求使用一个可选事务。这意味着第一个 SQL 语句应该从池中检索连接,启动事务,在请求处理完成后,应该提交事务(如果抛出异常则回滚)并关闭连接。当然,如果需要,必须可以进行更细粒度的事务管理。

Play 2 是否支持此功能?我可能可以自己实现它,但我正在寻找现成的解决方案。

我查看了 DB 对象,但似乎 DB.withConnection 每次都使用新的连接(和事务)。

如果重要的话,我正在使用 Scala 和 Anorm db 库。

【问题讨论】:

  • 您至少需要指定您使用哪种数据库方法以及使用哪种语言(Java/Scala)
  • 我将 Scala 与 Anorm 数据库库一起使用。
  • 我期待更通用的解决方案,无需更改控制器,但它可能不存在。我会检查你的回复。
  • 使用我定义为尽可能通用的Transaction 操作。如果您想要每个控制器功能的事务,那么在那里提供它是有意义的。

标签: sql scala transactions anorm playframework-2.3


【解决方案1】:

DB.withTransaction 是您想要的。就像DB.withConnection 一样,它将为所有包含的 SQL 函数从连接池提供一个连接。由于您希望每个请求使用一个事务,因此在控制器函数中调用它似乎最有意义,并要求所有模型函数都具有隐式连接参数。

型号:

object Product {

    def checkInventory(id: Long)(implicit c: Connection): Int = SQL(...)

    def decrementInventory(id: Long, quantity: Int)(implicit c: Connection): Boolean = SQL(...)

}

object Cart {

    def addItem(id: Long, quantity: Int)(implicit c: Connection): Boolean = SQL(...)

}

控制器功能:

def addToCart(id: Long, quantity: Int) = Action {

    DB.withTransaction{ implicit connection =>
       if(Product.checkInventory(id) >= quantity && Product.decrementInventory(id, quantity)) {

        Cart.addItem(id, quantity)
        ....
       } else {
           BadRequest
       }
    }
}

免责声明:这显然不是逻辑上合理的购物车交易,只是使用数据库交易的简单说明。

按照documentation 中的Action 组合示例,您可以创建一个特殊的Transaction 操作,自动为每个请求提供事务:

object Transaction extends ActionBuilder[Request] {
    def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
        DB.withTransaction{implicit connection => block(request)}
    }
}

并像Action一样使用它:

def addToCart(id: Long, quantity: Int) = Transaction {
    Product.checkInventory(id)

    ...
}

陷阱:以这种方式为每个请求提供一个事务是很方便的,尤其是当你的大多数控制器函数应该代表原子操作时。但是,在将Result 返回给用户之前,此方法不会从事务中释放Connection。这意味着,如果您要返回一个需要很长时间为客户端提供服务/呈现的大型数据集,那么您保持连接的时间将比您真正需要的时间长得多。

【讨论】:

  • 让所有 DB.withConnection 都在行动中好吗?你能用蛋糕图案或 DaoManager 之类的东西完成更好的分层设计吗?
猜你喜欢
  • 2014-03-05
  • 2011-03-20
  • 2014-03-29
  • 1970-01-01
  • 2014-12-14
  • 2015-08-04
  • 1970-01-01
  • 2012-03-04
  • 1970-01-01
相关资源
最近更新 更多