Sql 每个请求播放2个事务
对我来说,最方便的事务管理是对整个http请求使用一个可选事务。这意味着第一条SQL语句应该从池中检索连接,启动事务,在请求处理完成后,应该提交事务(或者在抛出异常时回滚),并关闭连接。当然,如果需要,必须能够进行更细粒度的事务管理 游戏2是否支持开箱即用?我可能可以自己实现它,但我正在寻找现成的解决方案 我查看了DB对象,但似乎DB.withConnection每次都使用新的连接(和事务)Sql 每个请求播放2个事务,sql,scala,transactions,anorm,playframework-2.3,Sql,Scala,Transactions,Anorm,Playframework 2.3,对我来说,最方便的事务管理是对整个http请求使用一个可选事务。这意味着第一条SQL语句应该从池中检索连接,启动事务,在请求处理完成后,应该提交事务(或者在抛出异常时回滚),并关闭连接。当然,如果需要,必须能够进行更细粒度的事务管理 游戏2是否支持开箱即用?我可能可以自己实现它,但我正在寻找现成的解决方案 我查看了DB对象,但似乎DB.withConnection每次都使用新的连接(和事务) 我正在使用Scala和Anorm db库,如果有必要的话。db。withTransaction是您想要的
我正在使用Scala和Anorm db库,如果有必要的话。
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
}
}
}
免责声明:这显然不是一个逻辑合理的购物车事务,只是使用数据库事务的简单说明
在中的操作
组合示例之后,您可以执行一个特殊的事务
操作,自动为每个请求提供事务:
object Transaction extends ActionBuilder[Request] {
def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]) = {
DB.withTransaction{implicit connection => block(request)}
}
}
并像操作一样使用它:
def addToCart(id: Long, quantity: Int) = Transaction {
Product.checkInventory(id)
...
}
陷阱:以这种方式为每个请求提供事务是很方便的,特别是当您的大多数控制器函数都应该表示原子操作时。但是,在将
结果
返回给用户之前,此方法不会从事务中释放连接
。这意味着,如果返回的大型数据集需要很长时间才能为客户机提供服务/渲染,则连接的保留时间将比实际需要的时间长得多。您需要至少指定使用哪种DB方法以及使用哪种语言(Java/Scala)我将Scala与Anorm db库一起使用。我希望在不需要更改控制器的情况下使用更通用的解决方案,但它可能不存在。我将检查您的响应。使用我定义为尽可能一般的事务
操作。如果您希望为每个控制器功能提供事务,那么在那里配置它是有意义的。让所有DB.withConnection都运行好吗?你能用像蛋糕图案或DaoManager这样的东西以更少的冗长完成更好的分层设计吗?