在Read Committed隔离级别下,同一事务内的SELECT能否得到不同结果?
Read Committed隔离级别下同一事务内SELECT是否会返回不同结果?
哎,这个问题问得挺关键的,答案是会的!我结合PostgreSQL 9.6的官方文档给你掰扯明白:
Read Committed是PostgreSQL中的默认隔离级别。当事务使用此隔离级别时,SELECT查询(不带FOR UPDATE/SHARE子句)仅能看到查询开始前已提交的数据;它不会看到未提交的数据或查询执行期间并发事务提交的更改。实际上,SELECT查询看到的是查询开始瞬间的数据库快照……
划个核心重点:Read Committed隔离级别下,事务里的每一次SELECT都会生成独立的快照,而不是整个事务共用一个初始快照。这就意味着,同一事务中先后执行的SELECT,只要中间有其他并发事务提交了数据更改,后面的SELECT就能看到这些新提交的内容,结果自然和前面的不一样。
给你举个直观的例子:
假设你开启了一个事务:
BEGIN; -- 第一次执行SELECT,此时表`user`里只有1条记录:id=1, name='Alice' SELECT * FROM "user"; -- 这时候另一个独立事务提交了一条新记录:id=2, name='Bob' -- 回到当前事务,执行第二次SELECT SELECT * FROM "user"; COMMIT;
这时候第一次查询只会返回Alice的记录,第二次查询就能同时看到Alice和Bob的记录——两次结果完全不同。
不过要注意哦:单个SELECT查询在执行过程中是“原子”的,它自己执行期间并发提交的更改,不会被这个SELECT本身看到,文档里也明确说了这一点。但同一事务里的下一个SELECT,就会用自己新的快照,能看到之前提交的更改了。
内容的提问来源于stack exchange,提问作者Martin




