不可重复读和幻影读的区别是什么?
我读过维基百科上的隔离(数据库系统)文章,但我有一些怀疑。在下面的例子中,将会发生什么:不可重复读取和幻影读取?
# # # #事务
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
# # # #输出:
1----MIKE------29019892---------5000
# # # #事务B
UPDATE USERS SET amount=amount+5000 where ID=1 AND accountno=29019892;
COMMIT;
# # # #事务
SELECT ID, USERNAME, accountno, amount FROM USERS WHERE ID=1
另一个疑问是,在上面的示例中,应该使用哪个隔离级别?,为什么?
摘自维基百科(其中有非常详细的例子):
不可重复读取发生在这样的情况下:在事务过程中,一行被检索了两次,并且两次读取之间行中的值不同。
and
在事务过程中,当执行两个相同的查询,而第二个查询返回的行集合与第一个查询不同时,就会发生幻影读。
简单的例子:
User A runs the same query twice.
In between, User B runs a transaction and commits.
Non-repeatable read: The A row that user A has queried has a different value the second time.
Phantom read: All the rows in the query have the same value before and after, but different rows are being selected (because B has deleted or inserted some). Example: select sum(x) from table; will return a different result even if none of the affected rows themselves have been updated, if rows have been added or deleted.
在上面的示例中,要使用哪个隔离级别?
您需要什么样的隔离级别取决于您的应用程序。“更好的”隔离级别(例如降低并发性)的成本很高。
在您的示例中,您不会进行幻影读取,因为您只从单行(由主键标识)进行选择。您可以使用不可重复的读取,因此如果这是一个问题,您可能希望有一个隔离级别来防止这种情况。在Oracle中,事务A也可以发出SELECT FOR UPDATE,那么事务B在A完成之前不能更改行。