步步为营 剖析事务中最难的——隔离性

去年夏天,周末的一个周日下午,我去了一家新开的咖啡店。
店里装修得很有特色,靠窗的座位总是挤满了人。
我选了一个靠窗的座位,喝着咖啡,享受着阳光,看着人来人往。

当时,我的手机突然收到一条消息,是关于数据库隔离级别的讨论。
我突然想到,孤独就像这家咖啡馆的一个座位。
每个人都有自己的位置,但并不是每个位置都可以随意互换。

等等,还有一件事有一天我读了一篇关于数据库隔离级别的文章。
文章称,孤独案例就像咖啡店里的顾客。
他们都有自己的活动空间,但有时需要一些规则来确保每个人都能公平地使用这些空间来维持秩序。

例如,在“读未提交”隔离级别下;就像自助餐厅没有座位的人可以自动占据其他人的座位一样。
这可能会导致“脏读”问题。
在“可串行化”的隔离级别下,就像在自助餐厅里安排座位一样,只有每个人都坐在自己的座位上因为你可以坐着,它给了你指挥权,但也降低了效率。

我认为,就像这家咖啡馆一样,隔离级别的选择应该根据实际需求而定。
有时,为了效率和速度;您可能需要牺牲一些隐私。
有时,必须严格遵循隔离规则以确保数据的准确性和一致性。

但是这个例子是不是太简单了?数据库隔离后更加复杂;锁定装置;交易依赖性;等等。
我摇摇头,喝了最后一口拿铁。
我觉得这个问题需要深入研究。

【59、数据库的四种隔离级别】

哎呀,这个数据库的各个级别太多了,不胜枚举。
我们先来说说ReadUncommited。
这是最低的孤独。
如果你想一想,一个事务可以读取另一个事务尚未提交的数据,那么问题就出现了。
就像之前在公司的时候,同事A刚刚录入了一堆信息,我还没有提交。
我读了但是A后来数据被改变了,我读到的内容是错误的。
这就是所谓的脏读。
就好像他去买了一些药草,还没洗干净就开始吃一样。
后来,当他们洗完蔬菜后,吃的食物的味道就变了。

说到 ReadCommitted,这要好得多。
一个事务只能读取另一个事务附加的数据。
就像你买了一个菜,洗完之后就开始吃,味道应该是对的。
这样就避免了脏读,但是问题又来了,可能会出现不重复读。
例如,当你购买食物时,你会再次购买。
这次的菜是别人买的,不能再买第二次了。
这称为不可重复的课程。

然后汇报一下可重复读取(RepeatableRead),这个比较高级。
结果是无论读多少次,读到的数据都是一样的。
就像你买的蔬菜,第一次买的,还可以再买。
这避免了不可重复读取,但仍然存在可能发生幻读的问题。
比如你买了两次食物,第二次去的时候,出了一些新的食物,但你第二次买不到,这就是幻读。

最后是关于可序列化报告,这是最高级别的隔离。
所有事务均按顺序执行,从而避免任何冲突问题。
就像你去杂货店排队买菜一样,一步一步来,不会出现插队的情况。
这种数据收集提供了一致性和隔离性,但缺点是牺牲了系统的收敛性。
就像排队买菜一样,直接去超市货架肯定效率不高。

综上所述,数据隔离级别越高,数据的一致性和隔离性越好,但系统的负载和开销也越大。
像我们这样工作在业务系统的人应该根据自己的具体需求选择合适的隔离。
例如,如果我们公司有一个对性能要求很高的系统,那么我们可以使用读提交或可重复读。
而有些系统对数据一致性要求较高,那么我们就可以选择序列化。
然而,不同的数据库管理系统对个别领域的实现和支持可能有所不同,所以在使用它们之前要仔细研究。

数据库中的隔离级别

2 02 2 年,我接手了一个城市的一个大数据项目。
该项目涉及数千条交易记录,对数据一致性要求非常高。
起初我对数据库的隔离级别了解不多。
我只知道数据不应该是马虎的、重复的或假可读的。
我当时就很迷茫,不知道如何操作。

项目进行到一半的时候,突然发现有些数据读取的时候不一致。
后来我意识到这可能是由于隔离级别设置不正确造成的。
很快查了资料,了解到隔离有几个级别:未提交读、提交读、递归读、可序列化。

未提交的读取看起来我可以在执行之前读取另一个事务的数据。
这听起来不错,但可能会导致读数马虎。
当时我不明白脏读是什么意思,但后来我了解到这可能会导致数据不一致。

投入的阅读似乎比不投入的阅读要好得多。
它只能读取已提交事务所做的修改。
这样可以防止脏读,但可能会出现不可重复读和虚假读。
当时我心里想,这听起来不错,也许我会尝试一下。

Repeated Read 这个级别比较高级,保证同一个事务中多次读取相同数据的结果的一致性。
听起来很完美,但是当我在项目中使用它时,我发现幻读问题仍然存在。
可能我有偏见,以为只要用那个级别就没有问题。

最后,还有序列化能力。
这个级别好像是最高的了。
它提供最高级别的隔离,但性能也最高。
当时我觉得这个级别可能不适合我们的项目,因为性能太重要了。

最后,我选择致力于阅读,因为我觉得它平衡了一致性和性能。
不过,我也知道这个选择可能并不理想,因为幻读问题仍然存在。
不过后来我了解到,有些数据库系统,比如MySQL的InnoDB存储引擎,可以通过间隙锁等技术来避免假读。

这次经历让我深刻认识到选择数据库隔离级别并不是一件简单的事情,应该根据具体的应用场景和性能需求来评估。