出现当前可见版本的tuple已经被其他事务更新,而当前事务又需要更新此tuple时的处理如下:
1.如果当前的隔离级别为可串行化,则报错:可串行化失败,并abort当前事务
2.如果当前隔离级别为Read Commited,则判断该tuple的最新版本是否满足当前update的条件,如果满足,则更新之,否则直接返回,继续执行其它plan分支
1.如何标志一个版本:每个tuple在heap中的实际存储内加入三个标志,即xmin,xmax和cid。Xmin是创建该tuple的事务id,xmax是删除或更新该tuple的事务id。Cid在创建该tuple时是创建者的commandid–cmin,如果被同一事务删除或更新,则cid中包含了创建者的commandid cmin和删除者的commandid cmax,当该事务提交时,cid内存储最后操作该tuple的commandid cmax。
2.如何判断可见性:事务启动时,截取快照。Tuple可见的条件是:(xmin已经commit或者xmin是当前事务且当前cid > cmin)且(xmax尚未启动、比当前事务晚启动或xmax是当前事务但是cmax >当前cid)。从而,当前事务所作出的更新对当前事务的后续命令可见。
3.Halloween问题通过cid已经解决:同一cid作出的更改对该cid不可见。
4.当需要更新发现当前可见的tuple已经被其他事务更新的时候。按照隔离级别不同进行不同处理:在可串行化隔离级别下,记录出错,并且Abort当前事务(即在事务日志中记录abort);在ReadCommited隔离级别下,则尝试获得最新的tuple,并检验其是否符合当前scan条件,如符合则更新之。