我相当确定这有一个简单的解决方案,但到目前为止我还没有找到它。提供了一个隔离级别设置为 SERIALIZABLE 的 InnoDB MySQL 数据库,并给出以下操作:
BEGIN WORK;
SELECT * FROM users WHERE userID=1;
UPDATE users SET credits=100 WHERE userID=1;
COMMIT;
我想确保一旦事务中的 select 发出,对应于 userID=1 的行就被锁定以供读取,直到事务完成。就目前而言,如果事务正在进行,则对该行的 UPDATE 将等待事务完成,但 SELECT 只会读取先前的值。我知道这是在这种情况下的预期行为,但我想知道是否有办法锁定行,这样 SELECT 也会等到事务完成返回值?
我正在寻找的原因是,在某个时候,如果有足够多的并发用户,可能会发生这样的情况:当前一个交易正在进行时,其他人会读取“信用”来计算其他东西。理想情况下,其他人运行的代码应该等待事务完成才能使用新值,否则可能会导致不可逆转的异步问题。
请注意,我不想锁定整个表进行读取,只锁定特定行。
此外,我可以在表中添加一个布尔“锁定”字段并将其设置为 1 每次我开始事务时,但我并不觉得这是这里最优雅的解决方案,除非绝对没有其他方法可以直接通过mysql处理。