数据的isolation level有
read uncommited - problem dirty read
read commited - problem unrepated read
repeated read(snapshot) - problem write skew/ phantom write
serialized - no problem excpet performance
工作中,除了你碰到这种问题会深有体会,靠死记硬背其实很容易忘记。本文作者提供一个自己记忆的思路。其实我们都用过github的版本控制,结合一下就会记忆深刻。
其实我们用github,我们的每一次提交就是一次transaction,我们先从master拉下一个snapshoot, 开始修改是transaction begin,修改后在我们提交的时候,就是一个t'ransaction end。提交前,无论我们怎么重新读original code,代码都是不变的,这就是可重复读。但是提交后,当我们merge的时候,就会有surprise,因为别人也修改了同行代码。这就造成了phantom write/write skew。怎么解决呢,我们可以手动merge,(有些系统设计还真的实现了这个思路,比如当有version conflict的时候,把不同version都保存下来,在用户读的时候,提示用户去确认哪分是对的)。但是如何让系统自动做这个merge呢?这个很难,无论系统如何merge,都有导致update lost的可能性。所以我们如果真的想完全杜绝这个问题,只能用serialized了,其实就是加锁,行锁连带着行间锁,解决是解决问题,但是就是效率低。
有一个最新的技术就是serializable snapshot isolation(SSI),据说是serializability,同时performance比之前高,其实本质就是一个乐观锁,两个竞争的update,失败者重新retry呗,就像你提交比队友晚了,你就只能苦逼的merge呗。