2

トランザクション ブロックに含まれるテーブルの一意キー制約に問題がある。

重要な制約の目的は、プレーヤーがゲーム - チーム - ピリオド - ゴールタイム - プレーヤーごとに複数のゴールまたはアシストを持たないようにすることです。これは正常に機能し、スコアリング レコードが重複することはありません。

ただし、チームが間違ったゴール スコアラーまたはアシスト ゲッターを選択した場合 (たとえば、プレーヤー A がアシストを取得したが、ゴールのクレジットを取得する必要があった場合)、記録を更新したい場合、キーの制約により、プレーヤー 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") ) }
4

1 に答える 1

0

解決策は、1 回のクエリでゲーム全体を削除するか、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 INTOJDBC ラッパー ライブラリがサポートしていないため、できません)。

于 2012-12-13T01:21:09.343 に答える