Uri*_*Uri 7 playframework anorm playframework-2.0 playframework-2.1
假设我有以下方法:
在WebsitesList模型上:
def create(urls: List[String]) = DB.withTransaction(implicit c => {
val websites = urls.map(Website.create(_))
val listId: Option[Long] = SQL("INSERT INTO LIST (created_date, active) VALUES ({created_date}, {active})").
on('created_date -> new Date(), 'active -> true).
executeInsert()
websites.foreach(websiteId =>
SQL("INSERT INTO websites_list (list_id, website_id) VALUES ({listId}, {websiteId})").
on('listId -> listId.get, 'websiteId -> websiteId.id).executeInsert()
)
throw new Exception()
})
Run Code Online (Sandbox Code Playgroud)
并在网站模型:
def create(url: String): Website = DB.withConnection {
implicit c =>
val currentDate = new Date()
val insertedId: Option[Long] = SQL("insert into websites (url, Date_Added) values ({url}, {date})").
on('url -> url, 'date -> currentDate).
executeInsert()
Website(insertedId.get, url, currentDate)
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我在WebsitesList创建方法上启动一个事务,并且该方法调用网站模型的create方法.
我的目标是,如果由于某种原因无法创建WebsitesList,则删除创建的网站记录.为了测试它,我引发异常并且如预期的那样,不会创建WebsitesList和List记录.但是,网站记录在异常后不会回滚并保留在数据库中.
我的理论是,Website.create方法创建了一个新连接而不是使用现有连接.谁知道我怎么解决这个问题?
谢谢.
mab*_*aba 11
您可以更改签名以进行隐式连接,然后在create方法之外控制事务.
Website.scala
object Website {
def create(url: String): Website = {
DB.withConnection { implicit connection =>
createWithConnection(url)
}
}
def createWithConnection(url: String)(implicit connection: Connection): Website = {
val currentDate = new Date()
val insertedId: Option[Long] = SQL("insert into websites(url, Date_Added) values ({url}, {date})").
on('url -> url, 'date -> currentDate).
executeInsert()
Website(insertedId.get, url, currentDate)
}
}
Run Code Online (Sandbox Code Playgroud)
WebsiteList.scala
object WebsiteList {
def create(urls: List[String]) = DB.withTransaction(implicit c => {
createWithConnection(urls)
})
def createWithConnection(urls: List[String])(implicit connection: Connection) = {
val websites = urls.map(Website.createWithConnection)
val listId: Option[Long] = SQL("INSERT INTO LIST (created_date, active) VALUES ({created_date}, {active})").
on('created_date -> new Date(), 'active -> true).
executeInsert()
websites.foreach(websiteId =>
SQL("INSERT INTO websites_list (list_id, website_id) VALUES ({listId}, {websiteId})").
on('listId -> listId.get, 'websiteId -> websiteId.id).executeInsert()
)
throw new Exception()
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,WebsiteList我更改了DB.withConnectionto,DB.withTransaction因为您正在进行多次插入并希望它们在同一事务中一起提交.
这使您可以控制Connection应该共享的时间和位置.
例如,您可以在控制器中执行事务管理,该事务管理更好地了解应该使用事务的时间:
object SomeController extends Controller {
def someAction(someData: String) = Action { implicit request =>
DB.withTransaction { implicit connection =>
SomeModel.create(someData)
OtherModel.create(someData)
}
}
}
object SomeModel {
def create(data: String)(implicit connection: Connection) {
}
}
object OtherModel {
def create(data: String)(implicit connection: Connection) {
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2703 次 |
| 最近记录: |