postgresql - PostgreSQL 隔离级别的行为

标签 postgresql transactions isolation-level

我正在阅读 PostgreSQL Manual 的第 13.2 节,但发现文本描述不够清晰,缺乏实例。

比如下面两段,谁在学PostgreSQL就不清楚了:

INSERT with an ON CONFLICT DO UPDATE clause behaves similarly. In Read Committed mode, each row proposed for insertion will either insert or update. Unless there are unrelated errors, one of those two outcomes is guaranteed. If a conflict originates in another transaction whose effects are not yet visible to the INSERT, the UPDATE clause will affect that row, even though possibly no version of that row is conventionally visible to the command."

The Repeatable Read mode provides a rigorous guarantee that each transaction sees a completely stable view of the database. However, this view will not necessarily always be consistent with some serial (one at a time) execution of concurrent transactions of the same level. For example, even a read only transaction at this level may see a control record updated to show that a batch has been completed but not see one of the detail records which is logically part of the batch because it read an earlier revision of the control record.

有人可以举例说明这两段中的内容吗?

有谁知道在哪里可以找到 PostgreSQL 隔离级别行为的正式描述?我正在寻找这个,因为它是一个高级主题,我相信正式的描述将有助于阐明它是如何工作的,从而有助于避免事务之间的并发错误。

更新:我的另一个疑问是,当可序列化事务可以与其他隔离级别的其他事务同时运行时,如何根据数据库机制决定提交或中止它来处理可序列化事务?数据库是否决定可序列化事务的结果,就好像其他事务也在可序列化隔离下运行一样?

谢谢

更新 2:到目前为止,关于隔离级别的实现细节,我发现最好的是 PostgreSQL Wiki Serializable Page .

最佳答案

  • READ COMMITTED:每个 SQL 语句都会获取数据库的新快照,因此每个语句都会同时看到并发事务所做的更改一旦他们 promise 。不会出现序列化错误。

  • REPEATABLE READ:事务中的第一条语句拍摄了为整个事务保留的数据库快照,因此所有语句都看到相同的状态的数据库。如果您尝试修改在获取快照后已被并发事务修改的行,则可能会发生序列化错误。此隔离级别并不比READ COMMITTED昂贵。

  • SERIALIZABLE:任何可能导致结果与事务的某些串行执行顺序不一致的事务都将因串行化错误而中止。可能存在误报。此隔离级别比其他隔离级别更昂贵。

具体问题的答案:

  • INSERT ... ON CONFLICT 在读提交隔离中:

    如果事务 1 已插入一行,但尚未提交,则运行 INSERT ... ON CONFLICT 的事务 2 将等到事务 1 已提交或回滚,然后根据需要更新或插入。不会发生违反约束的情况。

  • 批处理作业和可重复读取:

    这一段是深色的;忽略它。它试图说明两个并发的可重复读取翻译可以产生与任何串行执行都不一致的结果。

    一个更好的例子可能是两个并发事务,它们都读取相同的数据并根据读取结果对其执行更新。这些事务中的每一个都看不到另一个事务的修改。

    查看“可序列化”下的 PostgreSQL Wiki 以获得更详细的示例。

  • 更新问题:

    这个问题我不是很清楚。

    可序列化的事务采用特殊的“SI”锁来跟踪读写访问并在提交后继续存在。它们不会阻止其他 session ,但用于确定是否存在可能 冲突。只有所有并发事务都使用可序列化隔离级别时,可序列化隔离级别才能正常工作。

关于postgresql - PostgreSQL 隔离级别的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50725403/

相关文章:

sql - 如何将连接列添加到现有表?

java - 接口(interface) javax.transaction.Transaction 的实现是否需要线程安全?

php - mysql 和 php PDO - 如果连接意外关闭,未提交的事务会发生什么?

java - 在 Websphere 数据源中为 Sybase 数据源设置隔离级别

database - READ_UNCOMMITTED 与无事务?

java - 方法名称execute 该语句不声明OUT 参数。使用 { ?= call ... } 声明一个

postgresql - JPA2 (EclipseLink) 和 PostgreSQL 的引用问题

sql - 尝试优化特定的 SQL 查询

sql-server - EF6 将每个存储过程调用包装在其自己的事务中。如何防止这种情况发生?

c# - 使用 Sql Transaction 和 Isolation Level 进行冗长的读取操作?