【问题标题】:Concurrent updates并发更新
【发布时间】:2021-09-23 19:58:58
【问题描述】:

我在 MySQL 中有一个存储用户余额的表:

我还有一个使用 Spring Boot 和 Kotlin(Restful 服务)构建的应用程序,每次进行交易时都需要更新余额表,但是该应用程序支持来自同一应用程序实例下的同一用户的多个同时连接,这里是我有问题的地方。

我有一个使用 R2dbcEntityTemplate 的数据更新方法:

此方法从表中读取当前余额,并基于此在每次进行交易时进行折扣,但是,如果用户并行执行多个请求,则其中几个请求可以读取相同的余额和折扣错误,例如:

我想做的是“并发更新安全”,但是,使用 R2dbc 的 API:

update balance
SET balance = balance - @amount
WHERE user = @user

【问题讨论】:

  • 你可能想看看locking strategies。链接的仓库有一些例子。我对 R2DBC 或 Kotlin 不太熟悉,但我认为这些示例仍然适用。
  • @HopeyOne 您好,非常感谢您的回答。有趣的是,在回复我自己的帖子时,我看到了您的回复。我会看看你的链接,看看我能不能得到更好的结果。谢谢!
  • 可以在表格中添加版本号列吗? Hibernate 可以自动处理这个问题(使用@Version),它可以允许多个实例安全地更新表。
  • @gidds 您好,非常感谢您的回答。在阅读了您的答案和 Hopey One asnwer 之后,如果您 我个人认为 不使用 R2dbc,它们结合起来是一个很好的解决方案。 Hibernate 尚不与 R2dbc 兼容,因为 Hibernate 阻塞并与非阻塞的 R2dbc 相悖(根据我阅读的最新文档,我不知道今天会怎样)。无论如何,即使不兼容,我认为这并不妨碍 Hibernate + R2dbc 的集成,尽管会浪费 R2dbc 的特性。

标签: spring spring-boot kotlin r2dbc r2dbc-mysql


【解决方案1】:

好吧,在更彻底地阅读了 R2dbc 文档后,发现可以从 R2dbcEntityTemplate 运行本机 SQL 查询,这不是我所期望的,但是它非常适合我的应用程序的并发级别。如果有人对此有更好的解决方案,那就太好了,请不要犹豫,因为我最初需要的是这样做,但不是使用本机 SQL 查询,而是直接使用 R2dbc API。这就是它最终的样子,它也可以在不丢失数据保真度的情况下异步执行:

【讨论】:

    猜你喜欢
    • 2020-01-11
    • 1970-01-01
    • 2022-01-21
    • 2019-08-02
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多