sql - PostgreSQL 是否保证两个同时提交的 `commit timestamp` 的唯一性?

标签 sql postgresql transactions transactional postgresql-9.5

上下文: 我公开了一个 API,该 API 仅提供 PostgreSQL 表中出现的新内容。 "new"表示自上次调用后添加。

为此,我打开了在我的 PostgreSQL 服务器中定义的 track_commit_timestamp 选项,并在此提交日期之前对表内容进行排序。它运作良好。

为了提供新的东西,我在我的 SQL 选择响应中保留了最近的提交时间戳,并使用它来构建下一个请求,就像一个起点(日期 >= 到这个值)。

但是,我对这种机制 (track_commit_timestamp) 有疑问:是否有可能 2 个同时提交具有相同的时间戳并且在同一时刻不“可见”?因此,如果我的“SQL select”请求在这个小间隔内执行,我会丢失第二个事务内容吗?

最佳答案

我认为“同时”在这里没有意义。

想象一下两个事务写入您的数据库 (A,B) 和一个从数据库读取 (C)。

time------------>
  A->|
  B------------>|
       C-->|

现在,(C) 当然​​会看到时间戳为 T1 的 A。 B 也有时间戳 T1 但尚未提交。结果,C 看不到它,因为它可能会被回滚。

因此,您只能可靠地访问在 C 启动之前完成的事务的数据。最新的可行时间戳正好在最早的并发事务之前。

有两种简化方法和一种替代方法可能对您有所帮助。

首先,如果您的所有事务都很短(比如不到 1 秒),那么您只需从事务的开始时间中减去 1 秒并读取早于该时间的更改。这实际上是很普遍可行的。

其次,如果并发性不是问题,您可以使用事务级别或通过显式锁定强制执行序列化。

另一种方法是不再担心时间戳,而是将您的情况视为变化流。这将是各种基于触发器的复制系统或在 9.5(?) 及版本 10 中作为附加组件支持的逻辑复制所采用的方法。

关于sql - PostgreSQL 是否保证两个同时提交的 `commit timestamp` 的唯一性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51271012/

相关文章:

mysql - 将 id 替换为现有查询中另一个表的名称

asp.net - 如何解决 group by 中的 "Error converting data type varchar to numeric"问题?

sql - 获取多个字段的不同信息,其中一些字段为 NULL

android - Firestore 断开连接

mysql - 通过 mysql workbench 将 csv 导入表时的整数值不正确

mysql - 如果触发器中存在条件,如何在 MySQL 表中插入记录

sql - 选择查询以选择小于或等于 postgresql 中的当前日期的最接近日期

sql - 使用函数(而非触发器)中的旧值填充 Postgres 表

.net - ADO.NET Entity Framework 中事务的 MSDTC 问题

java - 只有一个事务数据源的 Spring @Transactional 行为