Idempotent insertion

28 views
Skip to first unread message

Roy Phillips

unread,
Apr 17, 2016, 8:18:04 AM4/17/16
to Slick / ScalaQuery
A pattern I often use in database access, similar to upsert, is to insert if the row doesn't exists else return the existing row.
Here's an example of my current implementation: I query for the row using its natural key, on which there is a unique constraint, if it's found, that row is returned, otherwise I insert a new row.
This is executed transactionally, and if two threads attempt the save action concurrently, causing a duplicate key error, I re-query to get the row that 'won', and return it.
Does anyone see any problems with this approach, or know of a better way to achieve this result?
(the magic number "23505" is the standardized JDBC error code for attempted duplicate key insertion - I don't use a raw string in my code, I have an appropriate constant)

  def idemInsert(event: DonationEvent) = {

   val action = findQuery(event) flatMap {

     case Some(existing) =>

       DBIO.successful(existing)

     case None =>

       saveAction(event)

   }

   db.run(action.transactionally)

     .map(Some(_))

     .recoverWith {

       case e: PSQLException if e.getSQLState == "23505" =>

         db.run(findQuery(event))

     }

 }

~                            



Reply all
Reply to author
Forward
0 new messages