问题描述:

Having a problem with a unique key constraint on a table involved in a transactional block.

The purpose of the key constraint is to prevent a player from having more than one goal or assist per game-team-period-goaltime-player. This works fine, no duplicate scoring records, great.

However, in cases where a team chooses the wrong goal scorer or assist getter (e.g. playerA got the assist but should have gotten credit for the goal), and then wants to update the record, the key constraint prevents the update from occurring as playerA, at the point of updating, will have both a goal and an assist on the same goal.

I should mention that I am using a JDBC SQL wrapper, so I do not have direct control over the generated SQL.

In an attempt to workaround this I decided to delete the existing goal and insert, all within a transactional block. Same deal, the key constraint is violated. Is it possible to delete and insert within the same transactional block? The code that generates the SQL looks something like:

db.handle withSession { implicit ss: SS =>

ss.withTransaction {

val result = for{

d <- teams.map{id=> model.delete(gameID, id)}

s <- rows.map{x=> model.insert(x)}

} yield s

}

}

if(result.forall(_.isRight)) Right

else { ss.rollback; Left( i18n("not updated") ) }

网友答案:

The solution was to delete the entire game in a single query, or, in the event of only 1 team's stats being submitted for update (allowed in our system), deleting that team's stats for the target game.

In the case of a full stats delete we have:

db.handle withSession { implicit ss: SS =>
  ss.withTransaction {
    val result = for{
      d <- model.delete(gameID)
      s <- rows.map{x=> model.insert(x)}
    } yield s
  }
}
if(result.forall(_.isRight)) Right
else { ss.rollback; Left( i18n("not updated") ) }

The key bit is that it appears one cannot perform multiple delete queries followed by multiple inserts to repopulate the deleted data in a transactional block where a key constraint exists that would otherwise be broken by the non-deletion of to-be inserted data.

Not sure if that makes sense or if it's even correct ;-), but performing the delete in a single query does allow the inserts that follow to execute without issue.

Best of both worlds, can keep desired key constraint, and perform transactional delete/insert (note: I cannot REPLACE INTO as the JDBC wrapper library does not support it).

相关阅读:
Top