14

Spring Data JPA を使用すると、同じトランザクション (REQUIRES_NEW) 内に次のフローがあります。

  1. この Spring Data JPA リポジトリ メソッドを使用して、一連のユーザーの予測を削除します。

    @Query(value = "DELETE FROM TRespuestaUsuarioPrediccion resp WHERE resp.idEvento.id = :eventId AND resp.idUsuario.id = :userId")
    @Modifying
    void deleteUserPredictions(@Param("userId") int userId, @Param("eventId") int eventId);
    
  2. 新しいユーザーの予測を挿入し、マスター オブジェクト (イベント) を保存します。

    eventRepository.save(event);
    

このサービスが終了すると、コミットは AOP によって行われますが、最初の試行でのみ機能します...次の試行では機能しません...

イベントの予測エントリを反復処理して内部の各エントリを更新せずに、この状況を管理するにはどうすればよいですか?

アップデート

私はそれを試してみましたが、うまくいきません(アダプターは以前に削除したオブジェクトを挿入します):

@Transactional(propagation=Propagation.REQUIRES_NEW, rollbackFor=PlayTheGuruException.class)
private void updateUserPredictions(final TUsuario user, final TEvento event, final SubmitParticipationRequestDTO eventParticipationRequestDTO) 
{
    eventRepository.deleteUserPredictions(user.getId(), event.getId());
    EventAdapter.predictionParticipationDto2Model(user, event, eventParticipationRequestDTO);
    eventRepository.save(event);
}
4

2 に答える 2

19

Hibernate はコマンドの順序を変更しました。以下の順序で動作します: すべての SQL および二次キャッシュの更新を特別な順序で実行して、外部キー制約に違反できないようにします。

    1. Inserts, in the order they were performed
    2. Updates
    3. Deletion of collection elements
    4. Insertion of collection elements
    5. Deletes, in the order they were performed 

そして、まさにその通りです。フラッシュするとき、Hibernate は削除ステートメントの前にすべての挿入を実行します。可能なオプションは次のとおり
です。 1. 削除の直後に entityManager.flush() を明示的に呼び出す。または 2. 可能な限り既存の行を更新し、残りから ToBeDeleted List を作成します。これにより、既存のレコードが新しい値で更新され、完全に新しいレコードが保存されます。

于 2015-12-08T11:19:36.953 に答える
1

PostgreSQL (およびおそらく他のデータベースも) には、コミットまで制約を延期する可能性があります。つまり、トランザクションで重複を受け入れますが、コミット時に一意の制約を適用します。

ALTER TABLE <table name> ADD CONSTRAINT <constraint name> UNIQUE(<column1>, <column2>, ...) DEFERRABLE INITIALLY DEFERRED;
于 2020-09-04T06:42:44.317 に答える