AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 273213
Accepted
Gandolf989
Gandolf989
Asked: 2020-08-05 11:23:33 +0800 CST2020-08-05 11:23:33 +0800 CST 2020-08-05 11:23:33 +0800 CST

我需要在我的清除功能中定期提交

  • 772

我编写了一个在 Postgres 9.6 中运行的清除函数。该函数遍历我们应用程序中的所有表,从最底层的子表开始,到最顶层的父表结束,并根据日期或客户进行清除。当我们在生产和测试版中运行它时,会同时发生其他进程,并且数据库正在根据我未提交的删除获得阻塞锁。一种可能的解决方案是每隔一千左右行进行一次提交。但是我是 Postgres 的新手,我无法让 Postgres 9.6 在循环中进行提交。Postgres 9.6 可能不会这样做,而 Postgres 12 可能会。我们正在迁移到 Postgres 12。

有没有办法让提交在 Postgres 9.6 中工作?我包含了一些测试代码,以便您可以自己测试提交。我的实际代码要复杂得多。

谢谢

\timing

DROP TABLE IF EXISTS _tmp_test_transactions_table;
CREATE TABLE _tmp_test_transactions_table ( pkey INTEGER );

create or replace function _tmp_test_transactions ( p_number_of_rows INTEGER )
returns int language plpgsql
as
$fun$
DECLARE
   v_counter     INTEGER := 0;
   v_final_count INTEGER := 0;
BEGIN
   START TRANSACTION ISOLATION LEVEL READ COMMITTED;

   LOOP
      v_counter := v_counter + 1;
      EXIT WHEN v_counter > p_number_of_rows;
      
      IF MOD( v_counter, 10 ) = 0
      THEN
         COMMIT;
         START TRANSACTION ISOLATION LEVEL READ COMMITTED;
      END IF;
   END LOOP;

   SELECT COUNT(*) 
     INTO v_final_count
     FROM _tmp_test_transactions_table;

   RAISE NOTICE 'Inserted % rows in the _tmp_test_transactions_table table', v_final_count;
   COMMIT;
END
$fun$;

SELECT _tmp_test_transactions( 100 );
psql:bbyrd_test_transactions.sql:36: ERROR:  unsupported transaction command in PL/pgSQL
CONTEXT:  PL/pgSQL function _tmp_test_transactions(integer) line 6 at SQL statement
Time: 0.473 ms
postgresql transaction
  • 2 2 个回答
  • 3250 Views

2 个回答

  • Voted
  1. Best Answer
    Daniel Vérité
    2020-08-06T10:32:20+08:002020-08-06T10:32:20+08:00

    PostgreSQL 函数中不允许事务控制(提交、回滚)。

    从 PostgreSQL 11 开始,可以在过程中使用(请参阅文档中的CREATE PROCEDURE)。事实上,这是函数和过程之间的主要区别。

    在 PostgreSQL 11 之前,在循环内提​​交的能力来自客户端超越 SQL 的编程。psqlCLI 当然可以发出提交和回滚,但它没有编程语言中的一些基本结构,例如循环。

    • 1
  2. Gandolf989
    2020-08-07T05:53:32+08:002020-08-07T05:53:32+08:00

    我运行了一个测试以使用一个程序提交,它运行良好。

    谢谢

    \timing
    Timing is on.
    DROP TABLE IF EXISTS _tmp_test_transactions_table;
    DROP TABLE
    Time: 38.583 ms
    CREATE TABLE _tmp_test_transactions_table ( pkey INTEGER );
    CREATE TABLE
    Time: 17.007 ms
    create or replace procedure _tmp_test_transactions ( p_number_of_rows INTEGER )
    language plpgsql
    as
    $fun$
    DECLARE
       v_counter     INTEGER := 0;
       v_final_count INTEGER := 0;
       v_dummy       INTEGER;
    BEGIN
       TRUNCATE TABLE _tmp_test_transactions_table;
       LOOP
          v_counter := v_counter + 1;
          EXIT WHEN v_counter > p_number_of_rows;
    
          INSERT INTO _tmp_test_transactions_table VALUES ( v_counter );
          COMMIT;
       END LOOP;
    
       SELECT COUNT(*)
         INTO v_final_count
         FROM _tmp_test_transactions_table;
    
       RAISE NOTICE 'Inserted % rows in the _tmp_test_transactions_table table', v_final_count;
    
       RAISE EXCEPTION 'This is an error, roll back';
    END
    $fun$;
    CREATE PROCEDURE
    Time: 5.104 ms
    CALL _tmp_test_transactions( 100 );
    psql:run_commit_test.sql:34: NOTICE:  Inserted 100 rows in the _tmp_test_transactions_table table
    psql:run_commit_test.sql:34: ERROR:  This is an error, roll back
    CONTEXT:  PL/pgSQL function _tmp_test_transactions(integer) line 22 at RAISE
    Time: 116.180 ms
    SELECT COUNT(*) FROM _tmp_test_transactions_table;
     count
    -------
       100
    (1 row)
    
    • 0

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve