Отправка записей мастеру mysql и чтение подчиненному в slick

С помощью Slick и Master/Slave, настроенных с MySQL, как я могу гарантировать, что записи (INSERT, UPDATE и т. д.) отправляются на мастер, а чтения (SELECT) отправляются на ведомые?


person theon    schedule 15.10.2013    source источник


Ответы (1)


Согласно документации MySQL, нам нужно установить Connection#setReadOnly(true|false).

Хороший способ сделать это в slick — добавить следующие функции в код вашей базы данных:

/**
 * 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
}

Затем вы можете написать такие запросы:

/**
 * 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
}
person theon    schedule 15.10.2013
comment
Если вы получаете java.sql.SQLException: при запуске Database.threadLocalSession.conn.setReadOnly(false) не выбрана база данных, это было исправлено для меня путем обновления до MySQL Connector 5.1.32. - person Ariel Kogan; 18.08.2014