postgresql - 使用带有存储库的 Spring 4 data jpa 增加或减少计数器值的预期方法是什么?

标签 postgresql transactions sql-update spring-data-jpa spring-transactions

给定以下场景:

  • 一家商店销售产品 A、B 和 C。
  • 库存数量为 A := 100, B := 100, C := 100
  • 一个购物车包含 50 个 A 和 80 个 B

我们有一个业务服务提供结帐(ShoppingCart 购物车)方法。这个方法应该做两件事务性的事情:

  1. 保留购物车
  2. 根据产品数量减少店铺库存

所以在我们的示例中,结帐后,我们希望商店库存为 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/

相关文章:

sql-update - 从另一个表更新多个列 - 需要 Oracle 格式

python - 当 SQLAlchemy 引发 ProgrammingError 时保留中止的事务

postgresql - 如何在 Kibana 中可视化来自 Postgresql 的数据?

sql-server - 处理 SQL Server catch 语句中的回滚

Python SQL 更新查询 : string or integer address expected instead of instance instance

多个 UNIQUE 字段的 ON DUPLICATE KEY UPDATE 的 MySQL 行为

sql - GROUP BY 整数值的区间

postgresql - 更新中变量的使用(已编辑)

mysql - 回滚试运行事务后无法继续执行进一步操作

transactions - Spring 数据 JPA : manual commit transaction and restart new one