【问题标题】:Keep data consistent with async HTTP requests使数据与异步 HTTP 请求保持一致
【发布时间】:2020-01-15 07:39:07
【问题描述】:

我正在使用 Play Framework 和 MariaDB 编写一个 Web 应用程序。用户在他的帐户上有余额,可以通过对应用程序的请求来消费。今天,当用户向应用程序发送 2 个请求时,无法确定第二个请求会从第一个请求中获取余额状态。导致数据不一致。

处理这个问题的“默认”方式是什么?在每次更新余额之后/之前使用锁定列更新和读取? MariaDB 有内置的锁机制吗?重新考虑异步请求?

感谢您的建议。

【问题讨论】:

  • 交易有什么问题?
  • 我将事务视为在一个事务中为多个数据库请求保持数据一致性的一种方式。如果一个请求失败,整个过程回滚。在这里,我实际上必须处理多个 HTTP 请求。我已经在一个 HTTP 请求期间将 DB 事务用于多个 DB 请求。
  • 那么你有一个very simple view of transactions。
  • 这实际上是我体验它们的方式。这就是我问这个问题的原因。
  • 事务还可以确保(取决于隔离级别)一切都像隔离操作一样完成(也就是说,在事务期间不会“允许”另一个冲突操作发生)

标签: mysql sql playframework mariadb


【解决方案1】:

您可以使用InnoDB 存储引擎提供的FOR UPDATE 事务隔离级别。

这将保证在第一个事务完成之前,第二个请求甚至不会看到锁定的记录。

【讨论】:

  • 我会试试这个选项:)
【解决方案2】:

另一种选择是使用带有保护子句的原子语句。

UPDATE account SET balance = balance - X WHERE id = Y and balance >= X

当余额超过X 时,这将从余额中扣除X。两个请求不可能执行任何“奇怪”的操作。如果0行受到影响,则提现失败,否则返回1行受到影响。

也可以使用更严格的隔离级别 (REPEATABLE READ),但它可能会比其他方法更复杂。您需要重试失败的事务,而其他解决方案完全避免了这种情况。

【讨论】:

    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 2012-03-09
    • 2015-10-24
    • 2018-04-10
    相关资源
    最近更新 更多