简体   繁体   English

具有可序列化隔离级别的两个 PostgreSQL 事务发生冲突

[英]Conflict on two PostgreSQL transactions with serializable isolation level

I have two concurrent SQL transactions with the most strict level of isolation (serializable)我有两个并发 SQL 事务,具有最严格的隔离级别(可序列化)

According to here :根据这里

The SQL standard defines four levels of transaction isolation. SQL 标准定义了四个级别的事务隔离。 The most strict is Serializable, which is defined by the standard in a paragraph which says that any concurrent execution of a set of Serializable transactions is guaranteed to produce the same effect as running them one at a time in some order最严格的是 Serializable,它是由标准在一段中定义的,它说一组 Serializable 事务的任何并发执行都保证产生与以某种顺序一次运行一个相同的效果

Or from MSDN regarding SET TRANSACTION ISOLATION LEVEL:或从 MSDN 关于 SET TRANSACTION ISOLATION LEVEL:

Places a range lock on the data set, preventing other users from updating or inserting rows into the data set until the transaction is complete.在数据集上放置一个范围锁,防止其他用户在事务完成之前更新或插入数据集。 This is the most restrictive of the four isolation levels.这是四个隔离级别中限制最大的。 Because concurrency is lower, use this option only when necessary.由于并发性较低,因此仅在必要时使用此选项。 This option has the same effect as setting HOLDLOCK on all tables in all SELECT statements in a transaction.此选项与在事务中的所有 SELECT 语句中的所有表上设置 HOLDLOCK 的效果相同。

But you see in the middle of the second transaction the table is empty.但是你看到在第二个事务的中间,表是空的。 How is that possible and how can I fix it??这怎么可能,我该如何解决?

具有可序列化隔离级别的两个 Postgres 事务的冲突

This is a consequence of the way Postgres provides system catalogs.这是 Postgres 提供系统目录方式的结果。 The relevant note in the documentation is clear enough:文档中的相关注释已经足够清楚了:

Internal access to the system catalogs is not done using the isolation level of the current transaction.对系统目录的内部访问不是使用当前事务的隔离级别完成的。 This means that newly created database objects such as tables are visible to concurrent Repeatable Read and Serializable transactions, even though the rows they contain are not.这意味着新创建的数据库对象(例如表)对并发可重复读取和可序列化事务可见,即使它们包含的行不可见。

The example you provided does not break the cited rules about the serializable isolation level.您提供的示例没有违反有关可序列化隔离级别的引用规则。 Note, that you start the second transaction when the table was dropped and created by the first transaction.请注意,当第一个事务删除并创建表时,您启动第二个事务。 The resulting behavior is as expected.结果行为符合预期。

If you had started both transactions before the table was dropped, then one of them would be suspended until the other completes.如果您在删除表之前启动了两个事务,那么其中一个将被挂起,直到另一个完成。

The SQL Server documentation is clearly not relevant. SQL Server 文档显然不相关。

But yes, that looks like a PostgreSQL bug that you should report.但是,是的,这看起来像是您应该报告的 PostgreSQL 错误。 But please with an SQL script, not with an animated GIF...但是请使用 SQL 脚本,而不是使用动画 GIF...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM