我正在阅读PostgreSQL Manual的第13.2节,但文字说明发现不够明确,缺乏例子。
例如,以下两段并不清楚谁在学习PostgreSQL:
使用ON CONFLICT DO UPDATE子句的INSERT行为类似。在阅读中 提交模式,建议插入的每一行都将插入或更新。 除非存在无关错误,否则保证这两种结果之一。如果 冲突起源于另一个影响尚未可见的交易 对于INSERT,UPDATE子句将影响该行,即使可能 该命令通常不会显示该行的任何版本。“
和
可重复读取模式为每次交易提供严格的保证 看到一个完全稳定的数据库视图。但是,此视图不一定总是与某个序列(一次一个)执行同一级别的并发事务一致。例如,即使是此级别的只读事务,也可能会看到一个控制记录已更新,以显示批处理已完成但未看到其中一个逻辑上属于批处理的详细记录,因为它读取了控制记录的早期版本
有人可以举例说明这两段中的内容吗?
有谁知道我在哪里可以找到PostgreSQL隔离级别行为的正式描述?我正在寻找这个,因为它是一个高级主题,我相信正式的描述将有助于澄清它是如何工作的,因此,有助于避免事务之间的并发错误。
更新:我有另一个疑问是,如果数据库机器决定提交或中止它,当它可以与其他隔离级别的其他事务同时运行时,如何处理可序列化事务?数据库是否决定可序列化事务的结果,就好像其他事务也是使用可序列化隔离运行一样?
由于
更新2 :到目前为止,我发现隔离级别的实施细节最好的是PostgreSQL Wiki Serializable Page。
答案 0 :(得分:3)
READ COMMITTED
:每个SQL语句都会获取数据库的新快照,因此每个语句都会始终看到并发事务所做的更改。承诺。不会发生序列化错误。
REPEATABLE READ
:事务中的第一个语句获取为整个事务保留的数据库的快照,因此所有语句都看到数据库的相同状态。如果您尝试在拍摄快照后修改已由并发事务修改的行,则可能会发生序列化错误。此隔离级别并不比READ COMMITTED
贵。
SERIALIZABLE
:任何可能导致与某些事务的串行执行顺序不一致的结果的事务都将因序列化错误而中止。可能存在误报。这种隔离级别比其他级别贵。
具体问题的答案:
INSERT ... ON CONFLICT
:
如果事务1已插入一行但尚未提交,则运行INSERT ... ON CONFLICT
的事务2将等待事务1已提交或回滚,然后根据需要进行更新或插入。不会发生约束违规。
批处理作业和REPEATABLE READ
:
这段是黑暗的;忽略它。它试图说明两个并发的可重复读取转换可能产生与任何串行执行不一致的结果。
更好的示例可能是两个并发事务,它们读取相同的数据并根据读取结果对它们执行更新。这些交易中的每一个都看不到另一个交易的修改。
在“可序列化”下查看PostgreSQL Wiki以获取更详细的示例。
更新问题:
这个问题我不太清楚。
可序列化事务采用特殊的“SI”锁定,可以跟踪读写访问并在提交后继续运行。它们不会阻止其他会话,但会用于确定可能是否存在冲突。只有所有并发事务使用可序列化隔离级别时,可序列化隔离级别才能正常工作。
答案 1 :(得分:0)
关于更新
中的问题数据库是否决定可序列化事务的结果,就好像其他事务也是使用可序列化隔离运行的那样?"
答案是否定的。
只能在可序列化隔离级别的并发事务之间验证可序列化性能。例如,给定两个事务T1和T2交错:
T1: begin
T1: set transaction isolation level read committed;
T1: update addresses set street = 'Sun street' where id = 1
T2: begin
T2: set transaction isolation level serializable;
T2: select street from addresses where id = 1
T2: update addresses set street = 'Sea street' where id = 2
T1: select street from addresses where id = 2
T1: commit
T2: commit
T1和T2都会提交。但是,如果T1设置为可序列化隔离,则T2将中止。