给定以下场景:
- 一家商店销售产品 A、B 和 C。
- 库存数量为 A := 100, B := 100, C := 100
- 一个购物车包含 50 个 A 和 80 个 B
我们有一个业务服务提供结帐(ShoppingCart 购物车)方法。这个方法应该做两件事务性的事情:
- 保留购物车
- 根据产品数量减少店铺库存
所以在我们的示例中,结帐后,我们希望商店库存为 A := 50、B := 20 和 C := 100。
我们目前使用两种存储库方法来做到这一点:
- CartRepository.save(ShoppingCart 购物车)
- 并且,对于每个包含的产品 ShopStockRepository.incrementStock(productId, -1 * 产品数量)
incrementStock 使用@Modifying 和@Query 注释实现为自定义更新查询。查询使用 UPDATE SET 语句来减少相关商品的商店库存。
不幸的是,数据库已正确更新,但商店商品对象未刷新。
使用集成测试,我们发现,如果我们将 EntityManager 注入(inject)结帐服务并建议它手动刷新每个产品,那么一切似乎都有效。但这是处理这种增量更新的正确方法吗???
我们可以想到的替代方法是读取产品、更新值并将其保存回来,但这不会导致竞争条件吗?我们是否必须实现某种锁定?
希望你能帮忙,我们已经为此苦苦挣扎了好几天:-/
马吕斯
最佳答案
您所做的是正确的,但是如果您希望下次获取实体时更新该值,则需要添加 @Modifying(clearAutomatically = true)
。
例如
public interface UsersRepository extends JpaRepository<Users, String> {
@Modifying(clearAutomatically = true)
@Query("update #{#entityName} u set u.sent = u.sent + :sentIncrement, u.receipts = u.receipts + :receiptsIncrement where u.id = :id")
int incrementSentAndReceipts(@Param("id") String id,
@Param("sentIncrement") int sentIncrement,
@Param("receiptsIncrement") int receiptsIncrement);
}
缺点是每次执行该查询时,都会清除一级缓存,您将强制 hibernate 去数据库刷新数据。
关于postgresql - 使用带有存储库的 Spring 4 data jpa 增加或减少计数器值的预期方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31271929/