相关疑难解决方法(0)

我可以选择插入到同一个未提交事务中的数据吗?

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

如果我开始一个事务,插入一些数据,我是否能够在之后立即选择它们 - 仍然在同一个但未提交的事务中?如果是,在并发事务的情况下,这种行为是否可以像提到的事务隔离一样以类似的方式改变?

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

postgresql transaction

31
推荐指数
2
解决办法
3万
查看次数

对子集聚合的建模约束?

我正在使用 PostgreSQL,但我认为大多数高端数据库必须具有一些类似的功能,而且,它们的解决方案可能会启发我的解决方案,所以不要考虑这个特定于 PostgreSQL 的解决方案。

我知道我不是第一个尝试解决这个问题的人,所以我认为这里值得一问,但我正在尝试评估建模会计数据的成本,以便从根本上平衡每笔交易。会计数据是仅附加的。此处的总体约束(以伪代码编写)可能大致如下:

CREATE TABLE journal_entry (
    id bigserial not null unique, --artificial candidate key
    journal_type_id int references  journal_type(id),
    reference text, -- source document identifier, unique per journal
    date_posted date not null,
    PRIMARY KEY (journal_type_id, reference)
);

CREATE TABLE journal_line (
    entry_id bigint references journal_entry(id),
    account_id int not null references account(id),
    amount numeric not null,
    line_id bigserial not null unique,
    CHECK ((sum(amount) over (partition by entry_id) = 0) -- this won't work
);
Run Code Online (Sandbox Code Playgroud)

显然,这样的检查约束永远不会起作用。它按行操作,可能会检查整个数据库。所以它总是会失败并且做起来很慢。

所以我的问题是对这种约束进行建模的最佳方法是什么?到目前为止,我基本上已经研究了两个想法。想知道这些是否是唯一的,或者是否有人有更好的方法(除了将其留给应用程序级别或存储过程)。

  1. 我可以借用会计界关于原始分录和最终分录(普通日记帐与总分类帐)之间差异的概念的一页。在这方面,我可以将其建模为附加到日志条目的日志行数组,对数组强制执行约束(在 PostgreSQL 术语中,从 …

postgresql database-design data-integrity

14
推荐指数
1
解决办法
2272
查看次数

如何在交易 ID 环绕后比较 xmin 和 txid_current()?

除了常规列之外,Postgres 表还有各种可用的系统列。其中之一,xmin,存储用于创建行的事务 ID。它的数据类型是xid,一个四字节整数,在某个点环绕(即不一定是唯一的)。该函数txid_current()反过来返回当前事务 ID,但作为bigint,因为它“使用“纪元”计数器进行了扩展,因此它不会在安装的生命周期内回绕”(引用手册)。

如果尚未发生交易回绕,则两个值似乎都匹配:

# CREATE TABLE test (label text);
CREATE TABLE
# INSERT INTO test VALUES ('test') RETURNING txid_current();
 txid_current 
--------------
   674500
(1 row)
INSERT 0 1
# SELECT xmin FROM test;
  xmin  
--------
 674500
(1 row)
Run Code Online (Sandbox Code Playgroud)

但我想知道:这两个值总是具有可比性吗?据我了解,txid_current()将在交易 ID 环绕(最多 2^32 个交易)后继续提供唯一值,xmin并将从零开始。这意味着两者都在那时开始返回不同的值?

如果这是真的,有没有办法来提取规则xid一的txid_current()结果,以便它匹配xmin的表(例如铸造项目txid_current(),以整数)?

编辑:更清楚地说明我关心事务 ID 环绕之后会发生什么,这很可能发生在 2^32 事务之前很久。感谢 Daniel Vérité 在评论中指出这一点。

postgresql transaction postgresql-9.5

13
推荐指数
1
解决办法
6120
查看次数

有没有办法在 Postgres 中获取事务提交时间戳?

我有数据拉取功能,可以在 5 秒内根据modified_timestamp列从 Postgres 表中抓取所有数据。它的工作方式如下:

  1. SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp
  2. _some_persisted_timestamp = CURRENT_TIMESTAMP
  3. 处理从步骤 1接收到的数据
  4. 睡眠 5 秒
  5. 转到步骤 1

其中modified_timestamp使用触发器更新(在任何行更新modified_timestamp变为 之后CURRENT_TIMESTAMP)。它工作正常,直到我注意到CURRENT_TIMESTAMPPostgres 实际上是事务开始时间戳并且一些更新丢失了。他们为什么会迷路?这很简单 - 在我执行查询时,SELECT * FROM my_table WHERE modified_timestamp > _some_persisted_timestamp一些更改已经发生,但modified_timestamp在更新_some_persisted_timestamp之前,因为事务仍在进行中。

当更新对其他事务可见(换句话说,事务提交时间戳)而不是 CURRENT_TIMESTAMP 或 clock_timestamp()时,可以通过在步骤 2 中 分配时间戳来轻松解决此问题。

我阅读了文档,但没有发现与事务提交时间戳相关的任何内容。你能不能给点建议?

顺便说一句,我知道逻辑解码,我知道这种机制在理论上更适合我的需求,但有一些实际问题不允许我使用它。

postgresql timestamp

8
推荐指数
1
解决办法
6037
查看次数

这个语句是如何在 Postgres 中更新 3 行的?

我很好奇这个语句是如何在 Postgres 中更新 3 行的。在我运行它的所有其他时间,它会更新 0 或 1。有没有办法找出哪些行?

bestsales=# update keyword set revenue = random()*10 where id = cast(random()*99999 as int);
UPDATE 3
Run Code Online (Sandbox Code Playgroud)

id 是主键。

 id               | integer                        | not null default nextval('keyword_id_seq'::regclass)
    "keyword_pkey" PRIMARY KEY, btree (id)
Run Code Online (Sandbox Code Playgroud)

我尝试将其运行为SELECT

bestsales=# select * from keyword where id = cast(random()*99999 as int);
  id   |       keyword       | seed_id | source | search_count | country | language | volume | cpc  | competition | modified_on | google_violation | revenue | bing_violation
-------+---------------------+---------+--------+--------------+---------+----------+--------+------+-------------+-------------+------------------+---------+---------------- …
Run Code Online (Sandbox Code Playgroud)

postgresql random update

4
推荐指数
2
解决办法
247
查看次数