交易性捕获22

时间:2012-12-08 23:33:25

标签: mysql insert transactions block

在事务块中涉及的表上存在唯一键约束的问题。

关键约束的目的是防止玩家拥有多个目标或协助每个游戏 - 团队 - 期间 - 目标时间 - 玩家。这很好,没有重复的得分记录,很棒。

但是,如果球队选择错误的射门得分者或辅助吸气者(例如,球员获得了助攻但应该得到了目标的信任),然后想要更新记录,则关键约束会阻止更新发生作为球员A,在更新时,将同时拥有目标和助攻。

我应该提到我正在使用JDBC SQL包装器,因此我无法直接控制生成的SQL。

为了解决此问题,我决定删除现有目标并在事务块中插入所有目标。相同的交易,违反了关键约束。是否可以在同一个事务块中删除和插入?生成SQL的代码类似于:

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") ) }

1 个答案:

答案 0 :(得分:0)

解决方案是在一个查询中删除整个游戏,或者,如果只有1个团队的统计数据被提交进行更新(在我们的系统中允许),则删除该团队的目标游戏统计数据。

如果是完整统计删除,我们有:

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") ) }

关键位是,似乎无法执行多个删除查询,然后多次插入以在事务块中重新填充已删除的数据,其中存在密钥约束,否则将被未删除的待插入数据破坏

不确定这是否有意义或者它是否正确;-),但在单个查询中执行删除确实允许后续插入执行而没有问题。

两全其美,可以保持所需的键约束,并执行事务删除/插入(注意:我不能REPLACE INTO,因为JDBC包装器库不支持它。)