在读已提交隔离模式下,当扫描的某个点之后在前一个点发生了插入时,索引顺序扫描可能会导致丢失行。
当扫描已经读取了一条记录,该记录后来被更新并放置在距离扫描点当前到达的位置较远的位置时,就会出现重复行。
为什么索引顺序扫描不会因页面拆分而导致丢失/重复行?
想象一下具有如下页面的索引:
| 页 | 键 | 下一页 |
|---|---|---|
| 1 | 000-099 | 2 |
| 2 | 100-199 | 3 |
| 3 | 200-299 |
现在假设您正在从第 1 页开始按升序键顺序读取行。
与此同时,另一个进程导致第 2 页分裂:
| 页 | 键 | 下一页 |
|---|---|---|
| 1 | 000-099 | 2 |
| 2 | 100-149 | 4 |
| 3 | 200-299 | |
| 4 | 150-199 | 3 |
一半的行已从第 2 页移至(新)第 4 页。下一页指针意味着您的扫描将继续按正确性所需的索引顺序查看键。
当您完成第 1 页时,下一页指针将带您到第 2 页,然后是第 4 页,然后是第 3 页。因此,页面拆分不会给您带来任何问题。
注意:SQL Server 在拆分期间使用独占锁存器保护所有受影响的页面,因此在拆分完成且所有链接更新之前,没有任何内容可以与它们交互。在分割期间不会错过行或读取它们两次。