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
행동을 할 수 자동으로 각 요청에 대한 조항 트랜잭션을 : 단지 Action
같은
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)
...
}
함정 : 이러한 방식으로 요청 당 트랜잭션을 제공하는 것이 편리합니다. 특히 대부분의 contro ller 함수는 원자 적 동작을 나타냅니다. 그러나이 방법은 Result
이 사용자에게 반환 될 때까지 트랜잭션에서 Connection
을 해제하지 않습니다. 즉, 클라이언트를 위해 서비스/렌더링하는 데 오랜 시간이 걸리는 대용량 데이터 세트를 반환하는 경우 실제로 필요한 것보다 훨씬 오래 동안 연결을 유지하게됩니다.
적어도 사용하는 DB 접근 방식과 언어 (Java/Scala)를 지정해야합니다. – biesior
Anorm db 라이브러리에서 Scala를 사용하고 있습니다. – vbezhenar
컨트롤러를 변경하지 않고보다 일반적인 솔루션을 기대했지만 실제로 존재하지 않습니다. 당신의 응답을 확인하겠습니다. – vbezhenar