Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending writes to the mysql master and reads to slave in slick

With Slick and a Master/Slave set up with MySQL, how do I ensure writes (INSERT, UPDATE, etc) are sent to the master and reads (SELECT) are send to the slaves?

like image 224
theon Avatar asked Oct 15 '13 09:10

theon


1 Answers

According to the MySQL docs on this, we need to set Connection#setReadOnly(true|false).

A nice way to do this in slick is to add the following functions to your database code:

/**
 * Runs a block of read only database code. No transaction required.
 */
def readOnly[T](f: => T) = db withSession {
  Database.threadLocalSession.conn.setReadOnly(true)
  f
}

/**
 * Runs a block of read/write database code in a transaction. 
 * Any exceptions will rollback any writes.
 */
def readWrite[T](f: => T) = db withTransaction {
  Database.threadLocalSession.conn.setReadOnly(false)
  f
}

Then you can write queries like so:

/**
 * Goes to slave
 */
def findUser(id: String) = readOnly {
  sql"SELECT ... FROM user WHERE id = $id".as[User].firstOption
}

/**
 * Goes to master
 */
def createUser(id: String) = readWrite {
  sqlu"INSERT INTO user VALUES(...)".execute
}
like image 187
theon Avatar answered Sep 20 '22 08:09

theon