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

标签 sql database postgresql

我在 PostgreSQL 工作,我刚刚开始学习同时工作的事务。 我的问题是当我运行整个脚本时,我得到了相同的事务 ID。 第一个元组应该有 1 个 id,第二个 2 应该有相同的 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;

最佳答案

该代码块在单个事务中执行。你还没有说它是如何执行的,但是如果你把它放在 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

您会看到交易编号符合预期,因为现在交易完全由手动控制 - 为第一个报表创建一个,为另外两个创建第二个。

关于sql - 请解释为什么脚本以这种方式工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56476813/

相关文章:

c# - 使数据库类静态化?

SQL 查询对多列中的条目进行计数

mysql - 如何在 mysql 中创建 ALPHANUMERIC 约束?

database - 可以在 heroku postgresql 中删除一行吗?

sql - 设置 session 授权和搜索路径

ruby-on-rails - Rails 4 session.id 偶尔为零

三个表之间的 MySQL 查询(还有 ORDER 和 LIMIT)

php - SQL 按 ID 列表过滤

schema - 存储SNMP数据的数据库方案

PostgreSQL - 将数据从一个表、数据库、服务器复制到另一个表、另一个数据库、服务器