9.5. 应用层的数据完整性检查

因为对 Postgres 的读动作不会锁定数据,不管事务是何隔离级别, 一个事务读取的数据可能被另一个事务覆盖。换句话说,如果一条 SELECT 返 回了一行,这并不意味着在返回该行时该行还存在 (比如说在语句完成或事务开始后的某时) 也不意味着在当前事务做提交或者回卷前该行被保护 不被并行的事务删除或更新。 即使该行"现在"仍然有效, 它在当前事务做提交或者回卷之前也可能被改变或者删除.

另外一个认识它的方法是每个事务都看到一个数据库内容的快照,而并行 执行的事物很可能看到不同的快照.因此不管怎样,整个"现在"的概念都 是值得怀疑的.不过如果客户端应用相互隔离,那么这就不是个大问题, 但是如果客户端之间在数据库外部相互之间通过通道通讯,那就可能有严重的 歧义.

要保证一行的实际存在和避免其被并行更新,我们必须使用 SELECT FOR UPDATE 或者 或者合适的 LOCK TABLE 语句。 (SELECT FOR UPDATE 只是对并行更新 锁住返回的行,而 LOCK TABLE 保护整个表.) 当从其他环境向 Postgres 里用可串行化模式移植应用时一定要把这些问题考虑进去。

注意: 在版本 6.5 前,Postgres 使用读动作锁,因而当从以前的 Postgres 版本向6.5(或更高版本)升级时也要考虑这些问题。.