也许这是一个愚蠢的初学者问题,但是我在任何地方都找不到答案。我到处都读到Transaction Isolation,它解决了并发事务中数据的可见性。我关心的是单个事务中的行为。

如果我开始一个事务,插入一些数据,我是否能够立即选择它们-仍在同一但尚未提交的事务中?
如果是,在并发事务中,是否可以像上述事务隔离那样以类似的方式更改此行为?

具体来说,我的目标是PostgreSQL 9.4。

#1 楼

是的。
您在同一事务中执行的所有操作对于同一事务中的后续命令都是可见的。只是在提交之前不进行其他交易。除Read uncommitted可能出现“脏读”(但它本身不会影响您的问题)外,所有隔离级别都适用。

它是基于TransactionId的MVCC模型(多版本并发控制)实现的确定每个表格行的相对年龄和可见性。在同一事务中写入的每个新行版本都具有相同的xmin,并且被视为“同时发生”。

在同一个中存在多个CTE(通用表表达式)的特殊情况命令。可能会认为这些顺序执行,但是除非一个CTE引用另一个,否则它们的顺序是任意的。从查询开始,所有这些人都看到相同的快照。这就是为什么不允许在同一查询的多个CTE中多次对同一行进行UPDATE:会导致模棱两可的原因。
示例:


返回pre-UPDATE仅使用SQL的列值-PostgreSQL版本

高级示例:


SELECT类型查询是唯一可以嵌套的类型吗?


#2 楼

让我们尝试一下:

CREATE OR REPLACE FUNCTION public.sp_get_user()
 RETURNS json
 LANGUAGE plpgsql
AS $function$BEGIN

INSERT INTO users (name, password) VALUES ('deadeye', 'test');
RETURN row_to_json(row) FROM (SELECT name, password FROM users WHERE name = 'deadeye') row;

END;$function$


现在,让我们测试一下:

SELECT sp_get_user();
{"name":"deadeye","password":"test"}


它有效!正如Erwin所说,交易中所做的一切在交易内部都是可见的。隔离仅在不同线程之间。