历史版本。 PostgreSQL 7.1 已结束支持。 请参阅 当前版本手册.
9.5. 应用级别的数据一致性检查 #
由于 Postgres
中的读操作不加锁(无论事务隔离级别如何),一个事务读取的数据仍可能被另一个并发事务覆盖。换句话说,某行被
SELECT 返回,并不意味着该行在返回的那一刻(即当前事务开始之后的某个时刻)仍然存在;该行可能已经被一个在本事务开始之后提交的已提交事务修改或删除。即使该行"现在"仍然有效,它也可能在当前事务提交或回滚之前被更改或删除。
换个角度想,每个事务看到的都是数据库内容的一个快照,而并发执行的事务完全可能看到不同的快照。因此"现在"这个概念本身就很可疑。如果客户端应用彼此隔离,这通常不是什么大问题;但如果客户端能通过数据库之外的渠道通信,就可能引发严重的混乱。
要确保某一行当前仍然存在,并保护它不受并发更新影响,就必须使用
SELECT FOR UPDATE 或适当的
LOCK TABLE 语句。(SELECT FOR UPDATE 只锁定返回的行以防止并发更新,而
LOCK TABLE 保护整张表。)从其他环境向
Postgres 移植应用时,应当考虑这一点。
注意
在 6.5 版之前,Postgres 使用的是读锁,因此从较早的 Postgres 版本升级到 6.5(或更高)时,上述考虑同样适用。