Skip to content

Instantly share code, notes, and snippets.

@bmc
Created September 25, 2012 19:21
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bmc/3783883 to your computer and use it in GitHub Desktop.
One way to do transactions in Play with Anorm
case class Article(...);
object Article {
import DBUtil._
def delete(id: Long): Either[String, Boolean] = {
withTransaction { implicit connection =>
SQL("DELETE FROM comments WHERE article_id = {id}").on("id" -> id).executeUpdate()
SQL("DELETE FROM appusers WHERE id = {id}").on("id" -> id).executeUpdate( )
Right(true)
}
}
}
object DBUtil {
def withTransaction[T](code: java.sql.Connection => Either[String,T]): Either[String, T] = {
val connection = play.db.DB.getConnection
val autoCommit = connection.getAutoCommit
try {
connection.setAutoCommit(false)
result = code(connection)
result.fold(
{ error => throw new Exception(error) },
{ _ => connection.commit() }
)
result
}
catch {
case e: Throwable =>
connection.rollback()
val msg = "Error, rolling back transaction: " + e.getMessage
Logger.error(msg)
Left(msg)
}
finally {
connection.setAutoCommit(autoCommit)
}
}
}
@bmc
Copy link
Author

bmc commented Sep 25, 2012

Anorm doesn't provide a built-in way to handle database transactions, but the code in TransactionUtil.scala, above, appears to get the job done. It assumes the caller will pass a block of code that returns Left(errorMessage) on error and Right(something: T) on success. Article.scala shows an example of its use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment