请解释为什么脚本会以这种方式工作

时间:2019-06-06 11:39:32

标签: sql database postgresql

我正在PostgreSQL中工作,我刚刚开始学习有关同时工作的事务。 我的问题是,当我运行整个脚本时,会得到相同的事务ID。 第一个元组应具有1个id,第二个元组应具有相同的id。

当我一行一行地运行脚本时,会得到正确的结果。 为什么这样工作?

DELETE FROM test;
INSERT INTO test VALUES (1, 'A');
BEGIN TRANSACTION;
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'C');
COMMIT TRANSACTION;

1 个答案:

答案 0 :(得分:2)

该代码块正在单个事务中执行。您还没有说过它是如何执行的,但是如果将其粘贴在pgadmin中并一起运行,或者将其放在文件中并用psql调用,则事务将自动启动并在最后提交。 BEGIN TRANSACTION行不会启动新事务,因为事务已经打开。这就是为什么一起执行所有操作会创建具有相同事务ID的行的原因。

为了演示,请逐行运行以下命令:

BEGIN;
INSERT INTO test VALUES (1, 'A');
SELECT txid_current();
BEGIN TRANSACTION;
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'C');
SELECT txid_current();
COMMIT TRANSACTION;

您将看到每个SELECT返回相同的ID。您还会在第二个BEGIN上看到一条消息,指出交易已经在进行中。

但是,如果仅突出显示(在pgadmin中)第一个INSERT并执行它(无需手动执行BEGIN),则这是该自动事务中唯一执行的行。然后,其余事务将在第二个事务中执行,无论您一次执行一行还是全部执行,因为该事务是手动处理的。

现在,如果您同时运行这些行:

BEGIN;
INSERT INTO test VALUES (1, 'A');
COMMIT;
BEGIN;
INSERT INTO test VALUES (2, 'B');
INSERT INTO test VALUES (3, 'C');
COMMIT;

然后运行:

SELECT xmin, *
FROM test

您会看到交易号符合预期,因为现在交易是完全由手动控制的-一个是为第一个语句创建的,另一个是为其他两个语句创建的。