我正在使用Play Framework和MariaDB编写Web应用程序。用户的帐户中有余额,可通过向应用程序请求来使用。如今,当用户向应用程序发送2个请求时,无法确定第二个请求将采用第一个请求的余额状态。这样会使数据不一致。
处理此问题的“默认”方式是什么?在每次更新余额之前/之前使用锁列更新和读取?有内置的MariaDB锁定机制吗?重新考虑异步请求?
感谢您的建议。
答案 0 :(得分:2)
您可以使用InnoDB
存储引擎提供的FOR UPDATE
事务隔离级别。
这将确保第二个请求在第一个事务完成之前甚至不会看到锁定的记录。
答案 1 :(得分:0)
另一种选择是使用带有保护子句的原子语句。
UPDATE account SET balance = balance - X WHERE id = Y and balance >= X
当余额超过X
时,这将从余额中扣除X
。两个请求不可能执行任何“怪异”的操作。如果受影响的行数为零,则提取失败,否则将返回受影响的行数。
也可以使用更严格的隔离级别(REPEATABLE READ
),但它会比其他选择更复杂。您需要重试失败的事务,而其他解决方案可以完全避免这种情况。