Skip to content

Instantly share code, notes, and snippets.

@mocyuto
Last active August 29, 2015 14:16
Show Gist options
  • Save mocyuto/a0e87bdc284239e56cf5 to your computer and use it in GitHub Desktop.
Save mocyuto/a0e87bdc284239e56cf5 to your computer and use it in GitHub Desktop.
It can create transaction over multi DB schema by Slick
package com.cyberz.foxapi.dao
import scala.slick.jdbc.JdbcBackend._
/**
* Created by Yuto Suzuki on 15/03/06.
*/
object BaseTransaction {
/**
* input is Database. this database transform to session.
* if something failed, it is roleback
* @param dbs DataSource which need to use transaction process
* @param f function which doing with Database.
* @tparam T
* @return
*/
def multiTransaction[T](dbs: Seq[Database])(f: Seq[Session] => T): T = {
val sessions = dbs.map(db => db.createSession())
sessions.foreach(s => s.conn.setAutoCommit(false))
try {
val res = f(sessions)
sessions.foreach(s => s.conn.setAutoCommit(true))
res
} catch {
case e: Exception =>
sessions.foreach(s => s.rollback())
throw e
} finally {
sessions.foreach(s => s.close())
}
}
}
package com.cyberz.foxapi.dao.transaction
import scala.slick.driver.MySQLDriver.simple._
/**
* Created by Yuto Suzuki on 15/03/06.
*/
case class User(id: Int, name: String)
trait UserComponent {
class User(tag: Tag) extends Table[User](tag, "tag") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id, name) <> (User.tupled, User.unapply)
}
def insert(id:Int, name:String)(implicit session: Session) = {
val entity = User(id,name)
query.insert(entity)
Q.queryNA[Int]("select LAST_INSERT_ID()").first
}
}
object AppTransaction {
def insertWithTransaction(id:Int, name:String)(implicit access: RequestUser) = {
val url1 = "jdbc:mysql://localhost:test/person"
val url2 = "jdbc:mysql://localhost:user/app"
val dbA = Database.forURL(url1,
user = "user1",
password = "password1",
driver = "com.mysql.jdbc.Driver")
val dbB = Database.forURL(url2,
user = "user2",
password ="password2",
driver = "com.mysql.jdbc.Driver")
// 
BaseTransaction.multiTransaction(Seq(dbA, dbB)) { sessions =>
// sessionA is a session of DbA
val sessionA = sessions(0)
// sessionB is a session of DbB
val sessionB = sessions(1)
// Insert into User on DbA
UserComponent.insert(id, name)(sessionA)
// Insert into User on DbB
UserComponent.insert(id, name)(sessionB)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment