Database transactions in Play framework scala applications (anorm)

后端 未结 2 2074
耶瑟儿~
耶瑟儿~ 2021-01-22 17:04

I am developing an application using Play framework and scala. I am using anorm for data-access layer. And I\'ve got a problem I could not solve.

Brief:

2条回答
  •  难免孤独
    2021-01-22 17:54

    The solution I've seen used elsewhere (principally in Squeryl), is roughly the following:

    import java.sql.Connection
    object Helper {
      private val conn: ThreadLocal[Connection] = new ThreadLocal
    
      def inTransaction[X](f: Connection => X) = {
        conn.get() match {
          case null =>
            DB.withConnection { newConn =>
              conn.set(newConn)
              try f(newConn)
              finally conn.set(null)
            }
          case c => f(c)
        }
      }
    }
    

    This way, the inTransaction method is re-entrant, so there's no harm in calling it redundantly inside dao.select.

    If you prefer, you can expose conn via a public method, and change the signature of f to => X - you lose some compile-time safety, but the API is a little cleaner.

    One pitfall with this approach is that connections are tied to threads, which may cause problems if you're using futures or actors, and a process can resume on a different thread (this is a tricky area anyway, but one you should be aware of).

    You might want to look into Squeryl too - it may already do what you need.

提交回复
热议问题