假设有一个数据库表:
account
id | balance
只有一种操作可以将资金从一个帐户转移到另一个帐户。如下所示:
START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE account_id = 1;
UPDATE account SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
从应用程序中,我们可以并行启动从Account1
到Account2
以及从Account2
到Account1
的传输。
我正在尝试理解Isolation level
保证。据我所知,在一个事务中不会出现Non-Repeatable
问题,因为不会对同一行进行两次读取。因此,我只需要关注Dirty Read
场景,Read Commited
* 隔离级别 * 为我提供了足够的保证,以确保我的应用程序能够正常工作?
我甚至不需要任何悲观锁来支持这种情况,我的想法对吗?如果不对,你能给予我一个例子,当我的保证被违反时?
2条答案
按热度按时间06odsfpq1#
是的,你是对的。默认的
READ COMMITTED
隔离级别保证没有并发事务可以看到脏数据,并且不会发生异常,因为UPDATE
在同一个事务中进行读写。如果第二笔资金从账户2转移到账户1的时间正好相同,那么可能会发生死锁。但这对数据完整性来说也没有问题。如果所有交易都先用较小的数字更新账户,那么就可以避免这种死锁,而不管转移是从哪个方向进行的。
s6fujrry2#
在这种情况下,您可以锁定表,直到事务完成
还可以锁定整个表,甚至指定一个条件:
在访问独占模式下锁定表帐户;