我正在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;
答案 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
您会看到交易号符合预期,因为现在交易是完全由手动控制的-一个是为第一个语句创建的,另一个是为其他两个语句创建的。