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 列表。这将确保使用新值更新现有记录并保存全新的记录。

于 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 回答