假设我想对包含两个查询的列进行原子更新:
SELECT num FROM table WHERE id = ?
将num
放在变量x
UPDATE table SET num = x + 1 WHERE id = ?
我在具有隔离级别的事务中进行这两个查询:可重复读取。
是否可能出现死锁情况? 我们假设有两个交易正在运行。
T1
读取值num并获取此行上的共享锁
T2
读取值num并获取此行上的共享锁
T1
现在想要获取写入的独占锁,但不能因为T2
持有共享锁
T2
现在想要获取写入的独占锁,但不能因为T1
持有共享锁
我们在这里陷入僵局。 但我尝试使用Spring数据JPA的代码,没有死锁。相反,我有竞争条件,最终递增的值小于预期值。如果我移动到隔离级别可序列化,那么我将陷入僵局,并且没有竞争条件。最终增量值很好。
我认为serializable只处理范围锁定。 为什么死锁发生在可序列化的隔离级别而不是可重复读取? 上面有两个查询。
PS:不要告诉我只使用一个UPDATE语句,我正在尝试学习如何使用两个语句手动执行原子更新,并在此处了解有关事务的更多信息。