spring-data-jpa 无法使用spring jpa获取更新的实体,唯一约束不会停止更新

z9gpfhce  于 2022-11-10  发布在  Spring
关注(0)|答案(2)|浏览(148)

我的情况:一个公共方法在开始时试图更新实体,最后,它试图查询更新后的实体并通过SNS发送消息。
第一个问题是,如果我调用DeviceDao.save(),我可以获得更新的实体,但是如果我调用UpdateClass中的自定义更新方法updateAsset,我就不能获得更新的实体。
第二个问题是代码仍然会传递到messagePublisher,即使UpdateClass.doSth()抛出org.hibernate.exception.ConstraintViolationException(我对资产ID有一个唯一约束),我也可以在“MessagePublisher.doRealthing()”中获得更新的实体,但最终,更新会回滚。
我的问题是,为什么我会得到那两个问题?对于第二个问题,除了提前查询资产Id,我如何才能避免它?
这是我的密码

public interface ExampleDeviceDao extends JpaRepository<Device, UUID>, JpaSpecificationExecutor<Device> {

    @Modifying
    @Query("UPDATE device a SET a.asset = ?1 WHERE a.device = ?2")
    int updateAsset(UUID asset, UUID device);

}

我的公共服务和方法:
第一个问题

uqjltbpv

uqjltbpv1#

问题可能是您的一级缓存(也称为持久性上下文)包含您正在执行DML语句的实体(update device ...)。Hibernate并不知道DML语句将更改持久性上下文中实体的状态,也无法对此执行任何明智的操作。因此,更改将在数据库上执行,但是持久性上下文中的实体仍然具有旧的状态,唯一明智的做法是刷新该实体(如果需要的话),或者通过调用EntityManager.detach()将其从持久性上下文中删除。
就我对你的第二个问题的理解,你的发布者代码发布了SNS消息,即使数据库事务失败。在这种情况下,你总是会有一个可能的问题,因为SNS客户端不是事务的一部分,也不可能是。
您可以通过以下方式在事务完成后发送消息

如果JVM在事务完成后关闭,但尚未发送SNS消息,或者SNS消息发送由于某种原因失败,则可能会错过发送某些消息。
为了解决这些问题,你通常会使用某种具有重试机制的作业队列。如果你对此感兴趣,你可以看看Blaze-Notify,它是一个工具包,可以用来有效地实现这一点。与其立即发送SNS消息,不如持久化一个代表消息的实体,该消息随后将被异步处理并利用重试机制发送。

q3aa0525

q3aa05252#

第一期请参见@ChristianBeikov answer
第二个问题和第一个问题的原因一样,你有

begin of updateAsset() method

device.get().setAsset(assetId); (1)
/**approach 1:*/
deviceDao.save(device.get()); (2)

Optional<Device> device = deviceDao.findById(deviceId); (3)
snsMessagePublisher.publishMessage(device.get()); (4)

end of updateAsset() method (5)

1.您在内存中更改设备(持久上下文)。
1.您将设备保存到数据库中。实际上,Hibernate此时什么也不做。您可以启用SQL日志记录,并看到什么也没有发生。
1.您从数据库中获取了Device。Hibernate在这里也不对数据库做任何操作。它只是从内存中获取您在(1)步骤中所做的更改。请使用SQL日志进行验证。
1.已更改的Device被发送到SNS。

  1. @Transactional方法结束。从方法返回后,Hibernate将从点(1)到数据库的所有更改刷新(请参阅SQL日志),并发生验证异常错误。但SNS消息已随新更改一起发送。数据库具有旧更改,因为事务已回滚。

可能的解决方案

您可以在发布SNS消息之前刷新数据库更改

deviceDao.save(device.get());
deviceDao.flushChanges();  // repository.flush()
snsMessagePublisher.publishMessage(device.get());

相关问题