在事务块中涉及的表上存在唯一键约束的问题。
关键约束的目的是防止玩家拥有多个目标或协助每个游戏 - 团队 - 期间 - 目标时间 - 玩家。这很好,没有重复的得分记录,很棒。
但是,如果球队选择错误的射门得分者或辅助吸气者(例如,球员获得了助攻但应该得到了目标的信任),然后想要更新记录,则关键约束会阻止更新发生作为球员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") ) }
答案 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包装器库不支持它。)